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>
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/destructive_filesource.h>
53 #include <ardour/auditioner.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/redirect.h>
56 #include <ardour/send.h>
57 #include <ardour/insert.h>
58 #include <ardour/connection.h>
59 #include <ardour/slave.h>
60 #include <ardour/tempo.h>
61 #include <ardour/audio_track.h>
62 #include <ardour/cycle_timer.h>
63 #include <ardour/named_selection.h>
64 #include <ardour/crossfade.h>
65 #include <ardour/playlist.h>
66 #include <ardour/click.h>
67 #include <ardour/data_type.h>
68 #include <ardour/source_factory.h>
71 #include <ardour/osc.h>
77 using namespace ARDOUR;
79 using boost::shared_ptr;
81 const char* Session::_template_suffix = X_(".template");
82 const char* Session::_statefile_suffix = X_(".ardour");
83 const char* Session::_pending_suffix = X_(".pending");
84 const char* Session::old_sound_dir_name = X_("sounds");
85 const char* Session::sound_dir_name = X_("audiofiles");
86 const char* Session::peak_dir_name = X_("peaks");
87 const char* Session::dead_sound_dir_name = X_("dead_sounds");
88 const char* Session::interchange_dir_name = X_("interchange");
90 Session::compute_peak_t Session::compute_peak = 0;
91 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
92 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
93 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
95 sigc::signal<int> Session::AskAboutPendingState;
96 sigc::signal<void> Session::SendFeedback;
98 sigc::signal<void> Session::SMPTEOffsetChanged;
99 sigc::signal<void> Session::SMPTETypeChanged;
100 sigc::signal<void> Session::PullupChanged;
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 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
281 cerr << "create failed\n";
282 throw failed_constructor ();
285 if (second_stage_init (new_session)) {
286 cerr << "2nd state failed\n";
287 throw failed_constructor ();
290 store_recent_sessions(_name, _path);
292 bool was_dirty = dirty();
294 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
296 Config->ParameterChanged.connect (mem_fun (*this, &Session::handle_configuration_change));
299 DirtyChanged (); /* EMIT SIGNAL */
303 Session::Session (AudioEngine &eng,
305 string snapshot_name,
306 AutoConnectOption input_ac,
307 AutoConnectOption output_ac,
308 uint32_t control_out_channels,
309 uint32_t master_out_channels,
310 uint32_t requested_physical_in,
311 uint32_t requested_physical_out,
312 jack_nframes_t initial_length)
315 _mmc_port (default_mmc_port),
316 _mtc_port (default_mtc_port),
317 _midi_port (default_midi_port),
318 pending_events (2048),
320 diskstreams (new DiskstreamList),
321 routes (new RouteList),
327 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
329 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
330 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
332 first_stage_init (fullpath, snapshot_name);
334 if (create (new_session, 0, initial_length)) {
335 throw failed_constructor ();
338 if (control_out_channels) {
339 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
346 if (master_out_channels) {
347 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
353 /* prohibit auto-connect to master, because there isn't one */
354 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
357 input_auto_connect = input_ac;
358 output_auto_connect = output_ac;
360 if (second_stage_init (new_session)) {
361 throw failed_constructor ();
364 store_recent_sessions(_name, _path);
366 bool was_dirty = dirty ();
368 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
371 DirtyChanged (); /* EMIT SIGNAL */
377 /* if we got to here, leaving pending capture state around
381 remove_pending_capture_state ();
383 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
384 _engine.remove_session ();
386 GoingAway (); /* EMIT SIGNAL */
392 /* clear history so that no references to objects are held any more */
396 /* clear state tree so that no references to objects are held any more */
402 terminate_butler_thread ();
403 terminate_midi_thread ();
405 if (click_data && click_data != default_click) {
406 delete [] click_data;
409 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
410 delete [] click_emphasis_data;
415 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
419 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
423 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
427 AudioDiskstream::free_working_buffers();
429 #undef TRACK_DESTRUCTION
430 #ifdef TRACK_DESTRUCTION
431 cerr << "delete named selections\n";
432 #endif /* TRACK_DESTRUCTION */
433 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
434 NamedSelectionList::iterator tmp;
443 #ifdef TRACK_DESTRUCTION
444 cerr << "delete playlists\n";
445 #endif /* TRACK_DESTRUCTION */
446 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
447 PlaylistList::iterator tmp;
457 #ifdef TRACK_DESTRUCTION
458 cerr << "delete audio regions\n";
459 #endif /* TRACK_DESTRUCTION */
461 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
462 i->second->drop_references ();
465 audio_regions.clear ();
467 #ifdef TRACK_DESTRUCTION
468 cerr << "delete routes\n";
469 #endif /* TRACK_DESTRUCTION */
471 RCUWriter<RouteList> writer (routes);
472 boost::shared_ptr<RouteList> r = writer.get_copy ();
473 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
474 (*i)->drop_references ();
477 /* writer goes out of scope and updates master */
482 #ifdef TRACK_DESTRUCTION
483 cerr << "delete diskstreams\n";
484 #endif /* TRACK_DESTRUCTION */
486 RCUWriter<DiskstreamList> dwriter (diskstreams);
487 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
488 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
489 (*i)->drop_references ();
493 diskstreams.flush ();
495 #ifdef TRACK_DESTRUCTION
496 cerr << "delete audio sources\n";
497 #endif /* TRACK_DESTRUCTION */
498 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
499 AudioSourceList::iterator tmp;
504 i->second->drop_references ();
509 audio_sources.clear ();
511 #ifdef TRACK_DESTRUCTION
512 cerr << "delete mix groups\n";
513 #endif /* TRACK_DESTRUCTION */
514 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
515 list<RouteGroup*>::iterator tmp;
525 #ifdef TRACK_DESTRUCTION
526 cerr << "delete edit groups\n";
527 #endif /* TRACK_DESTRUCTION */
528 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
529 list<RouteGroup*>::iterator tmp;
539 #ifdef TRACK_DESTRUCTION
540 cerr << "delete connections\n";
541 #endif /* TRACK_DESTRUCTION */
542 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
543 ConnectionList::iterator tmp;
553 if (butler_mixdown_buffer) {
554 delete [] butler_mixdown_buffer;
557 if (butler_gain_buffer) {
558 delete [] butler_gain_buffer;
561 Crossfade::set_buffer_size (0);
569 Session::set_worst_io_latencies ()
571 _worst_output_latency = 0;
572 _worst_input_latency = 0;
574 if (!_engine.connected()) {
578 boost::shared_ptr<RouteList> r = routes.reader ();
580 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
581 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
582 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
587 Session::when_engine_running ()
589 string first_physical_output;
591 /* we don't want to run execute this again */
593 first_time_running.disconnect ();
595 set_block_size (_engine.frames_per_cycle());
596 set_frame_rate (_engine.frame_rate());
598 /* every time we reconnect, recompute worst case output latencies */
600 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
602 if (synced_to_jack()) {
603 _engine.transport_stop ();
606 if (Config->get_jack_time_master()) {
607 _engine.transport_locate (_transport_frame);
615 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
617 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
619 /* existing state for Click */
621 if (_click_io->set_state (*child->children().front()) == 0) {
623 _clicking = click_requested;
627 error << _("could not setup Click I/O") << endmsg;
633 /* default state for Click */
635 first_physical_output = _engine.get_nth_physical_output (0);
637 if (first_physical_output.length()) {
638 if (_click_io->add_output_port (first_physical_output, this)) {
639 // relax, even though its an error
641 _clicking = click_requested;
647 catch (failed_constructor& err) {
648 error << _("cannot setup Click I/O") << endmsg;
651 set_worst_io_latencies ();
654 ControlChanged (Clicking); /* EMIT SIGNAL */
657 if (auditioner == 0) {
659 /* we delay creating the auditioner till now because
660 it makes its own connections to ports named
661 in the ARDOUR_RC config file. the engine has
662 to be running for this to work.
666 auditioner.reset (new Auditioner (*this));
669 catch (failed_constructor& err) {
670 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
674 /* Create a set of Connection objects that map
675 to the physical outputs currently available
680 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
682 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
684 Connection* c = new OutputConnection (buf, true);
687 c->add_connection (0, _engine.get_nth_physical_output (np));
692 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
694 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
696 Connection* c = new InputConnection (buf, true);
699 c->add_connection (0, _engine.get_nth_physical_input (np));
706 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
708 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
710 Connection* c = new OutputConnection (buf, true);
714 c->add_connection (0, _engine.get_nth_physical_output (np));
715 c->add_connection (1, _engine.get_nth_physical_output (np+1));
720 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
722 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
724 Connection* c = new InputConnection (buf, true);
728 c->add_connection (0, _engine.get_nth_physical_input (np));
729 c->add_connection (1, _engine.get_nth_physical_input (np+1));
738 /* create master/control ports */
743 /* force the master to ignore any later call to this */
745 if (_master_out->pending_state_node) {
746 _master_out->ports_became_legal();
749 /* no panner resets till we are through */
751 _master_out->defer_pan_reset ();
753 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
754 if (_master_out->add_input_port ("", this)) {
755 error << _("cannot setup master inputs")
761 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
762 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
763 error << _("cannot setup master outputs")
770 _master_out->allow_pan_reset ();
774 Connection* c = new OutputConnection (_("Master Out"), true);
776 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
778 c->add_connection ((int) n, _master_out->input(n)->name());
785 /* catch up on send+insert cnts */
789 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
792 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
793 if (id > insert_cnt) {
801 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
804 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
811 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
813 /* hook us up to the engine */
815 _engine.set_session (this);
820 osc->set_session (*this);
823 _state_of_the_state = Clean;
825 DirtyChanged (); /* EMIT SIGNAL */
829 Session::hookup_io ()
831 /* stop graph reordering notifications from
832 causing resorts, etc.
835 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
837 /* Tell all IO objects to create their ports */
844 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
845 if (_control_out->add_input_port ("", this)) {
846 error << _("cannot setup control inputs")
852 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
853 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
854 error << _("cannot set up master outputs")
862 /* Tell all IO objects to connect themselves together */
864 IO::enable_connecting ();
866 /* Now reset all panners */
868 IO::reset_panners ();
870 /* Anyone who cares about input state, wake up and do something */
872 IOConnectionsComplete (); /* EMIT SIGNAL */
874 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
876 /* now handle the whole enchilada as if it was one
882 /* update mixer solo state */
888 Session::playlist_length_changed (Playlist* pl)
890 /* we can't just increase end_location->end() if pl->get_maximum_extent()
891 if larger. if the playlist used to be the longest playlist,
892 and its now shorter, we have to decrease end_location->end(). hence,
893 we have to iterate over all diskstreams and check the
894 playlists currently in use.
900 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
904 if ((playlist = dstream->playlist()) != 0) {
905 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
908 /* see comment in playlist_length_changed () */
913 Session::record_enabling_legal () const
915 /* this used to be in here, but survey says.... we don't need to restrict it */
916 // if (record_status() == Recording) {
927 Session::set_auto_play (bool yn)
929 if (auto_play != yn) {
932 ControlChanged (AutoPlay);
937 Session::set_auto_return (bool yn)
939 if (auto_return != yn) {
942 ControlChanged (AutoReturn);
947 Session::set_crossfades_active (bool yn)
949 if (crossfades_active != yn) {
950 crossfades_active = yn;
952 ControlChanged (CrossFadesActive);
957 Session::set_do_not_record_plugins (bool yn)
959 if (do_not_record_plugins != yn) {
960 do_not_record_plugins = yn;
962 ControlChanged (RecordingPlugins);
967 Session::set_auto_input (bool yn)
969 if (auto_input != yn) {
972 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
973 /* auto-input only makes a difference if we're rolling */
975 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
977 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
978 if ((*i)->record_enabled ()) {
979 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
980 (*i)->monitor_input (!auto_input);
986 ControlChanged (AutoInput);
991 Session::reset_input_monitor_state ()
993 if (transport_rolling()) {
995 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
997 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
998 if ((*i)->record_enabled ()) {
999 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1000 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
1004 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1006 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1007 if ((*i)->record_enabled ()) {
1008 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1009 (*i)->monitor_input (Config->get_use_hardware_monitoring());
1017 Session::set_input_auto_connect (bool yn)
1020 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
1022 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1028 Session::get_input_auto_connect () const
1030 return (input_auto_connect & AutoConnectPhysical);
1034 Session::set_output_auto_connect (AutoConnectOption aco)
1036 output_auto_connect = aco;
1041 Session::auto_punch_start_changed (Location* location)
1043 replace_event (Event::PunchIn, location->start());
1045 if (get_record_enabled() && get_punch_in()) {
1046 /* capture start has been changed, so save new pending state */
1047 save_state ("", true);
1052 Session::auto_punch_end_changed (Location* location)
1054 jack_nframes_t when_to_stop = location->end();
1055 // when_to_stop += _worst_output_latency + _worst_input_latency;
1056 replace_event (Event::PunchOut, when_to_stop);
1060 Session::auto_punch_changed (Location* location)
1062 jack_nframes_t when_to_stop = location->end();
1064 replace_event (Event::PunchIn, location->start());
1065 //when_to_stop += _worst_output_latency + _worst_input_latency;
1066 replace_event (Event::PunchOut, when_to_stop);
1070 Session::auto_loop_changed (Location* location)
1072 replace_event (Event::AutoLoop, location->end(), location->start());
1074 if (transport_rolling() && get_auto_loop()) {
1076 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1078 if (_transport_frame > location->end()) {
1079 // relocate to beginning of loop
1080 clear_events (Event::LocateRoll);
1082 request_locate (location->start(), true);
1085 else if (seamless_loop && !loop_changing) {
1087 // schedule a locate-roll to refill the diskstreams at the
1088 // previous loop end
1089 loop_changing = true;
1091 if (location->end() > last_loopend) {
1092 clear_events (Event::LocateRoll);
1093 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1100 last_loopend = location->end();
1105 Session::set_auto_punch_location (Location* location)
1109 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1110 auto_punch_start_changed_connection.disconnect();
1111 auto_punch_end_changed_connection.disconnect();
1112 auto_punch_changed_connection.disconnect();
1113 existing->set_auto_punch (false, this);
1114 remove_event (existing->start(), Event::PunchIn);
1115 clear_events (Event::PunchOut);
1116 auto_punch_location_changed (0);
1121 if (location == 0) {
1125 if (location->end() <= location->start()) {
1126 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1130 auto_punch_start_changed_connection.disconnect();
1131 auto_punch_end_changed_connection.disconnect();
1132 auto_punch_changed_connection.disconnect();
1134 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1135 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1136 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1138 location->set_auto_punch (true, this);
1139 auto_punch_location_changed (location);
1143 Session::set_punch_in (bool yn)
1145 if (punch_in == yn) {
1151 if ((location = _locations.auto_punch_location()) != 0) {
1152 if ((punch_in = yn) == true) {
1153 replace_event (Event::PunchIn, location->start());
1155 remove_event (location->start(), Event::PunchIn);
1160 ControlChanged (PunchIn); /* EMIT SIGNAL */
1164 Session::set_punch_out (bool yn)
1166 if (punch_out == yn) {
1172 if ((location = _locations.auto_punch_location()) != 0) {
1173 if ((punch_out = yn) == true) {
1174 replace_event (Event::PunchOut, location->end());
1176 clear_events (Event::PunchOut);
1181 ControlChanged (PunchOut); /* EMIT SIGNAL */
1185 Session::set_auto_loop_location (Location* location)
1189 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1190 auto_loop_start_changed_connection.disconnect();
1191 auto_loop_end_changed_connection.disconnect();
1192 auto_loop_changed_connection.disconnect();
1193 existing->set_auto_loop (false, this);
1194 remove_event (existing->end(), Event::AutoLoop);
1195 auto_loop_location_changed (0);
1200 if (location == 0) {
1204 if (location->end() <= location->start()) {
1205 error << _("Session: you can't use a mark for auto loop") << endmsg;
1209 last_loopend = location->end();
1211 auto_loop_start_changed_connection.disconnect();
1212 auto_loop_end_changed_connection.disconnect();
1213 auto_loop_changed_connection.disconnect();
1215 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1216 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1217 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1219 location->set_auto_loop (true, this);
1220 auto_loop_location_changed (location);
1224 Session::locations_added (Location* ignored)
1230 Session::locations_changed ()
1232 _locations.apply (*this, &Session::handle_locations_changed);
1236 Session::handle_locations_changed (Locations::LocationList& locations)
1238 Locations::LocationList::iterator i;
1240 bool set_loop = false;
1241 bool set_punch = false;
1243 for (i = locations.begin(); i != locations.end(); ++i) {
1247 if (location->is_auto_punch()) {
1248 set_auto_punch_location (location);
1251 if (location->is_auto_loop()) {
1252 set_auto_loop_location (location);
1259 set_auto_loop_location (0);
1262 set_auto_punch_location (0);
1269 Session::enable_record ()
1271 /* XXX really atomic compare+swap here */
1272 if (g_atomic_int_get (&_record_status) != Recording) {
1273 g_atomic_int_set (&_record_status, Recording);
1274 _last_record_location = _transport_frame;
1275 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1277 if (Config->get_use_hardware_monitoring() && auto_input) {
1278 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1279 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1280 if ((*i)->record_enabled ()) {
1281 (*i)->monitor_input (true);
1286 RecordStateChanged ();
1291 Session::disable_record (bool rt_context, bool force)
1295 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1297 if (!Config->get_latched_record_enable () || force) {
1298 g_atomic_int_set (&_record_status, Disabled);
1300 if (rs == Recording) {
1301 g_atomic_int_set (&_record_status, Enabled);
1305 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1307 if (Config->get_use_hardware_monitoring() && auto_input) {
1308 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1310 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1311 if ((*i)->record_enabled ()) {
1312 (*i)->monitor_input (false);
1317 RecordStateChanged (); /* emit signal */
1320 remove_pending_capture_state ();
1326 Session::step_back_from_record ()
1328 g_atomic_int_set (&_record_status, Enabled);
1330 if (Config->get_use_hardware_monitoring()) {
1331 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1333 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1334 if (auto_input && (*i)->record_enabled ()) {
1335 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1336 (*i)->monitor_input (false);
1343 Session::maybe_enable_record ()
1345 g_atomic_int_set (&_record_status, Enabled);
1347 /* XXX this save should really happen in another thread. its needed so that
1348 pending capture state can be recovered if we crash.
1351 save_state ("", true);
1353 if (_transport_speed) {
1358 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1359 RecordStateChanged (); /* EMIT SIGNAL */
1366 Session::audible_frame () const
1369 jack_nframes_t offset;
1372 /* the first of these two possible settings for "offset"
1373 mean that the audible frame is stationary until
1374 audio emerges from the latency compensation
1377 the second means that the audible frame is stationary
1378 until audio would emerge from a physical port
1379 in the absence of any plugin latency compensation
1382 offset = _worst_output_latency;
1384 if (offset > current_block_size) {
1385 offset -= current_block_size;
1387 /* XXX is this correct? if we have no external
1388 physical connections and everything is internal
1389 then surely this is zero? still, how
1390 likely is that anyway?
1392 offset = current_block_size;
1395 if (synced_to_jack()) {
1396 tf = _engine.transport_frame();
1398 tf = _transport_frame;
1401 if (_transport_speed == 0) {
1411 if (!non_realtime_work_pending()) {
1415 /* take latency into account */
1424 Session::set_frame_rate (jack_nframes_t frames_per_second)
1426 /** \fn void Session::set_frame_size(jack_nframes_t)
1427 the AudioEngine object that calls this guarantees
1428 that it will not be called while we are also in
1429 ::process(). Its fine to do things that block
1433 _base_frame_rate = frames_per_second;
1437 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1439 // XXX we need some equivalent to this, somehow
1440 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1444 /* XXX need to reset/reinstantiate all LADSPA plugins */
1448 Session::set_block_size (jack_nframes_t nframes)
1450 /* the AudioEngine guarantees
1451 that it will not be called while we are also in
1452 ::process(). It is therefore fine to do things that block
1457 vector<Sample*>::iterator i;
1460 current_block_size = nframes;
1462 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1466 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1470 _passthru_buffers.clear ();
1471 _silent_buffers.clear ();
1473 ensure_passthru_buffers (np);
1475 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1479 #ifdef NO_POSIX_MEMALIGN
1480 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1482 posix_memalign((void **)&buf,16,current_block_size * 4);
1486 memset (*i, 0, sizeof (Sample) * current_block_size);
1490 if (_gain_automation_buffer) {
1491 delete [] _gain_automation_buffer;
1493 _gain_automation_buffer = new gain_t[nframes];
1495 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1497 boost::shared_ptr<RouteList> r = routes.reader ();
1499 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1500 (*i)->set_block_size (nframes);
1503 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1504 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1505 (*i)->set_block_size (nframes);
1508 set_worst_io_latencies ();
1513 Session::set_default_fade (float steepness, float fade_msecs)
1516 jack_nframes_t fade_frames;
1518 /* Don't allow fade of less 1 frame */
1520 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1527 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1531 default_fade_msecs = fade_msecs;
1532 default_fade_steepness = steepness;
1535 // jlc, WTF is this!
1536 Glib::RWLock::ReaderLock lm (route_lock);
1537 AudioRegion::set_default_fade (steepness, fade_frames);
1542 /* XXX have to do this at some point */
1543 /* foreach region using default fade, reset, then
1544 refill_all_diskstream_buffers ();
1549 struct RouteSorter {
1550 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1551 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1553 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1556 if (r1->fed_by.empty()) {
1557 if (r2->fed_by.empty()) {
1558 /* no ardour-based connections inbound to either route. just use signal order */
1559 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1561 /* r2 has connections, r1 does not; run r1 early */
1565 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1572 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1574 shared_ptr<Route> r2;
1576 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1577 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1581 /* make a copy of the existing list of routes that feed r1 */
1583 set<shared_ptr<Route> > existing = r1->fed_by;
1585 /* for each route that feeds r1, recurse, marking it as feeding
1589 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1592 /* r2 is a route that feeds r1 which somehow feeds base. mark
1593 base as being fed by r2
1596 rbase->fed_by.insert (r2);
1600 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1604 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1608 /* now recurse, so that we can mark base as being fed by
1609 all routes that feed r2
1612 trace_terminal (r2, rbase);
1619 Session::resort_routes ()
1621 /* don't do anything here with signals emitted
1622 by Routes while we are being destroyed.
1625 if (_state_of_the_state & Deletion) {
1632 RCUWriter<RouteList> writer (routes);
1633 shared_ptr<RouteList> r = writer.get_copy ();
1634 resort_routes_using (r);
1635 /* writer goes out of scope and forces update */
1640 Session::resort_routes_using (shared_ptr<RouteList> r)
1642 RouteList::iterator i, j;
1644 for (i = r->begin(); i != r->end(); ++i) {
1646 (*i)->fed_by.clear ();
1648 for (j = r->begin(); j != r->end(); ++j) {
1650 /* although routes can feed themselves, it will
1651 cause an endless recursive descent if we
1652 detect it. so don't bother checking for
1660 if ((*j)->feeds (*i)) {
1661 (*i)->fed_by.insert (*j);
1666 for (i = r->begin(); i != r->end(); ++i) {
1667 trace_terminal (*i, *i);
1674 cerr << "finished route resort\n";
1676 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1677 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1684 list<boost::shared_ptr<AudioTrack> >
1685 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1687 char track_name[32];
1688 uint32_t track_id = 0;
1690 uint32_t channels_used = 0;
1692 RouteList new_routes;
1693 list<boost::shared_ptr<AudioTrack> > ret;
1695 /* count existing audio tracks */
1698 shared_ptr<RouteList> r = routes.reader ();
1700 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1701 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1702 if (!(*i)->hidden()) {
1704 channels_used += (*i)->n_inputs();
1710 vector<string> physinputs;
1711 vector<string> physoutputs;
1712 uint32_t nphysical_in;
1713 uint32_t nphysical_out;
1715 _engine.get_physical_outputs (physoutputs);
1716 _engine.get_physical_inputs (physinputs);
1720 /* check for duplicate route names, since we might have pre-existing
1721 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1722 save, close,restart,add new route - first named route is now
1730 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1732 if (route_by_name (track_name) == 0) {
1736 } while (track_id < (UINT_MAX-1));
1738 if (input_auto_connect & AutoConnectPhysical) {
1739 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1744 if (output_auto_connect & AutoConnectPhysical) {
1745 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1751 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1753 if (track->ensure_io (input_channels, output_channels, false, this)) {
1754 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1755 input_channels, output_channels)
1760 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1764 if (input_auto_connect & AutoConnectPhysical) {
1765 port = physinputs[(channels_used+x)%nphysical_in];
1768 if (port.length() && track->connect_input (track->input (x), port, this)) {
1774 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1778 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1779 port = physoutputs[(channels_used+x)%nphysical_out];
1780 } else if (output_auto_connect & AutoConnectMaster) {
1782 port = _master_out->input (x%_master_out->n_inputs())->name();
1786 if (port.length() && track->connect_output (track->output (x), port, this)) {
1791 channels_used += track->n_inputs ();
1794 vector<string> cports;
1795 uint32_t ni = _control_out->n_inputs();
1797 for (n = 0; n < ni; ++n) {
1798 cports.push_back (_control_out->input(n)->name());
1801 track->set_control_outs (cports);
1804 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1805 track->set_remote_control_id (ntracks());
1807 new_routes.push_back (track);
1808 ret.push_back (track);
1811 catch (failed_constructor &err) {
1812 error << _("Session: could not create new audio track.") << endmsg;
1813 // XXX should we delete the tracks already created?
1821 if (!new_routes.empty()) {
1822 add_routes (new_routes, false);
1823 save_state (_current_snapshot_name);
1830 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1833 uint32_t bus_id = 1;
1838 /* count existing audio busses */
1841 shared_ptr<RouteList> r = routes.reader ();
1843 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1844 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1845 if (!(*i)->hidden()) {
1852 vector<string> physinputs;
1853 vector<string> physoutputs;
1855 _engine.get_physical_outputs (physoutputs);
1856 _engine.get_physical_inputs (physinputs);
1863 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1865 if (route_by_name (bus_name) == 0) {
1869 } while (bus_id < (UINT_MAX-1));
1872 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1874 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1875 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1876 input_channels, output_channels)
1880 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1884 if (input_auto_connect & AutoConnectPhysical) {
1885 port = physinputs[((n+x)%n_physical_inputs)];
1888 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1893 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1897 if (output_auto_connect & AutoConnectPhysical) {
1898 port = physoutputs[((n+x)%n_physical_outputs)];
1899 } else if (output_auto_connect & AutoConnectMaster) {
1901 port = _master_out->input (x%_master_out->n_inputs())->name();
1905 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1911 vector<string> cports;
1912 uint32_t ni = _control_out->n_inputs();
1914 for (uint32_t n = 0; n < ni; ++n) {
1915 cports.push_back (_control_out->input(n)->name());
1917 bus->set_control_outs (cports);
1920 ret.push_back (bus);
1924 catch (failed_constructor &err) {
1925 error << _("Session: could not create new audio route.") << endmsg;
1934 add_routes (ret, false);
1935 save_state (_current_snapshot_name);
1943 Session::add_routes (RouteList& new_routes, bool save)
1946 RCUWriter<RouteList> writer (routes);
1947 shared_ptr<RouteList> r = writer.get_copy ();
1948 r->insert (r->end(), new_routes.begin(), new_routes.end());
1949 resort_routes_using (r);
1952 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1953 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), (*x)));
1954 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1955 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1956 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1958 if ((*x)->master()) {
1962 if ((*x)->control()) {
1963 _control_out = (*x);
1970 save_state (_current_snapshot_name);
1973 RouteAdded (new_routes); /* EMIT SIGNAL */
1977 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1979 /* need to do this in case we're rolling at the time, to prevent false underruns */
1980 dstream->do_refill_with_alloc();
1983 RCUWriter<DiskstreamList> writer (diskstreams);
1984 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1985 ds->push_back (dstream);
1988 dstream->set_block_size (current_block_size);
1990 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1991 /* this will connect to future changes, and check the current length */
1992 diskstream_playlist_changed (dstream);
1994 dstream->prepare ();
1998 Session::remove_route (shared_ptr<Route> route)
2001 RCUWriter<RouteList> writer (routes);
2002 shared_ptr<RouteList> rs = writer.get_copy ();
2005 /* deleting the master out seems like a dumb
2006 idea, but its more of a UI policy issue
2010 if (route == _master_out) {
2011 _master_out = shared_ptr<Route> ((Route*) 0);
2014 if (route == _control_out) {
2015 _control_out = shared_ptr<Route> ((Route*) 0);
2017 /* cancel control outs for all routes */
2019 vector<string> empty;
2021 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2022 (*r)->set_control_outs (empty);
2026 update_route_solo_state ();
2028 /* writer goes out of scope, forces route list update */
2031 // FIXME: audio specific
2033 boost::shared_ptr<AudioDiskstream> ds;
2035 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2036 ds = at->audio_diskstream();
2042 RCUWriter<DiskstreamList> dsl (diskstreams);
2043 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2048 find_current_end ();
2050 update_latency_compensation (false, false);
2053 /* XXX should we disconnect from the Route's signals ? */
2055 save_state (_current_snapshot_name);
2057 /* try to cause everyone to drop their references */
2059 route->drop_references ();
2063 Session::route_mute_changed (void* src)
2069 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2071 if (solo_update_disabled) {
2078 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2080 shared_ptr<RouteList> r = routes.reader ();
2082 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2084 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2088 /* don't mess with busses */
2090 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2096 /* don't mess with tracks */
2098 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2103 if ((*i) != route &&
2104 ((*i)->mix_group () == 0 ||
2105 (*i)->mix_group () != route->mix_group () ||
2106 !route->mix_group ()->is_active())) {
2108 if ((*i)->soloed()) {
2110 /* if its already soloed, and solo latching is enabled,
2111 then leave it as it is.
2114 if (_solo_latched) {
2121 solo_update_disabled = true;
2122 (*i)->set_solo (false, src);
2123 solo_update_disabled = false;
2127 bool something_soloed = false;
2128 bool same_thing_soloed = false;
2129 bool signal = false;
2131 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2132 if ((*i)->soloed()) {
2133 something_soloed = true;
2134 if (dynamic_cast<AudioTrack*>((*i).get())) {
2136 same_thing_soloed = true;
2141 same_thing_soloed = true;
2149 if (something_soloed != currently_soloing) {
2151 currently_soloing = something_soloed;
2154 modify_solo_mute (is_track, same_thing_soloed);
2157 SoloActive (currently_soloing);
2164 Session::set_solo_latched (bool yn)
2166 if (yn != _solo_latched) {
2169 ControlChanged (SoloLatch);
2174 Session::update_route_solo_state ()
2177 bool is_track = false;
2178 bool signal = false;
2180 /* caller must hold RouteLock */
2182 /* this is where we actually implement solo by changing
2183 the solo mute setting of each track.
2186 shared_ptr<RouteList> r = routes.reader ();
2188 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2189 if ((*i)->soloed()) {
2191 if (dynamic_cast<AudioTrack*>((*i).get())) {
2198 if (mute != currently_soloing) {
2200 currently_soloing = mute;
2203 if (!is_track && !mute) {
2205 /* nothing is soloed */
2207 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2208 (*i)->set_solo_mute (false);
2218 modify_solo_mute (is_track, mute);
2221 SoloActive (currently_soloing);
2226 Session::modify_solo_mute (bool is_track, bool mute)
2228 shared_ptr<RouteList> r = routes.reader ();
2230 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2234 /* only alter track solo mute */
2236 if (dynamic_cast<AudioTrack*>((*i).get())) {
2237 if ((*i)->soloed()) {
2238 (*i)->set_solo_mute (!mute);
2240 (*i)->set_solo_mute (mute);
2246 /* only alter bus solo mute */
2248 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2250 if ((*i)->soloed()) {
2252 (*i)->set_solo_mute (false);
2256 /* don't mute master or control outs
2257 in response to another bus solo
2260 if ((*i) != _master_out &&
2261 (*i) != _control_out) {
2262 (*i)->set_solo_mute (mute);
2273 Session::catch_up_on_solo ()
2275 /* this is called after set_state() to catch the full solo
2276 state, which can't be correctly determined on a per-route
2277 basis, but needs the global overview that only the session
2280 update_route_solo_state();
2284 Session::route_by_name (string name)
2286 shared_ptr<RouteList> r = routes.reader ();
2288 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2289 if ((*i)->name() == name) {
2294 return shared_ptr<Route> ((Route*) 0);
2298 Session::route_by_id (PBD::ID id)
2300 shared_ptr<RouteList> r = routes.reader ();
2302 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2303 if ((*i)->id() == id) {
2308 return shared_ptr<Route> ((Route*) 0);
2312 Session::route_by_remote_id (uint32_t id)
2314 shared_ptr<RouteList> r = routes.reader ();
2316 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2317 if ((*i)->remote_control_id() == id) {
2322 return shared_ptr<Route> ((Route*) 0);
2326 Session::find_current_end ()
2328 if (_state_of_the_state & Loading) {
2332 jack_nframes_t max = get_maximum_extent ();
2334 if (max > end_location->end()) {
2335 end_location->set_end (max);
2337 DurationChanged(); /* EMIT SIGNAL */
2342 Session::get_maximum_extent () const
2344 jack_nframes_t max = 0;
2347 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2349 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2350 Playlist* pl = (*i)->playlist();
2351 if ((me = pl->get_maximum_extent()) > max) {
2359 boost::shared_ptr<Diskstream>
2360 Session::diskstream_by_name (string name)
2362 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2364 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2365 if ((*i)->name() == name) {
2370 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2373 boost::shared_ptr<Diskstream>
2374 Session::diskstream_by_id (const PBD::ID& id)
2376 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2378 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2379 if ((*i)->id() == id) {
2384 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2387 /* AudioRegion management */
2390 Session::new_region_name (string old)
2392 string::size_type last_period;
2394 string::size_type len = old.length() + 64;
2397 if ((last_period = old.find_last_of ('.')) == string::npos) {
2399 /* no period present - add one explicitly */
2402 last_period = old.length() - 1;
2407 number = atoi (old.substr (last_period+1).c_str());
2411 while (number < (UINT_MAX-1)) {
2413 AudioRegionList::const_iterator i;
2418 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2421 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2422 if (i->second->name() == sbuf) {
2427 if (i == audio_regions.end()) {
2432 if (number != (UINT_MAX-1)) {
2436 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2441 Session::region_name (string& result, string base, bool newlevel) const
2448 Glib::Mutex::Lock lm (region_lock);
2450 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2458 /* XXX this is going to be slow. optimize me later */
2463 string::size_type pos;
2465 pos = base.find_last_of ('.');
2467 /* pos may be npos, but then we just use entire base */
2469 subbase = base.substr (0, pos);
2473 bool name_taken = true;
2476 Glib::Mutex::Lock lm (region_lock);
2478 for (int n = 1; n < 5000; ++n) {
2481 snprintf (buf, sizeof (buf), ".%d", n);
2486 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2487 if (i->second->name() == result) {
2500 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2508 Session::add_region (boost::shared_ptr<Region> region)
2510 boost::shared_ptr<AudioRegion> ar;
2511 boost::shared_ptr<AudioRegion> oar;
2515 Glib::Mutex::Lock lm (region_lock);
2517 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2519 AudioRegionList::iterator x;
2521 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2523 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2525 if (ar->region_list_equivalent (oar)) {
2530 if (x == audio_regions.end()) {
2532 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2534 entry.first = region->id();
2537 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2549 fatal << _("programming error: ")
2550 << X_("unknown region type passed to Session::add_region()")
2557 /* mark dirty because something has changed even if we didn't
2558 add the region to the region list.
2564 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
2565 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2566 AudioRegionAdded (ar); /* EMIT SIGNAL */
2571 Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
2573 if (what_changed & Region::HiddenChanged) {
2574 /* relay hidden changes */
2575 RegionHiddenChange (region);
2580 Session::region_renamed (boost::shared_ptr<Region> region)
2582 add_region (region);
2586 Session::remove_region (boost::shared_ptr<Region> region)
2588 AudioRegionList::iterator i;
2589 boost::shared_ptr<AudioRegion> ar;
2590 bool removed = false;
2593 Glib::Mutex::Lock lm (region_lock);
2595 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2596 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2597 audio_regions.erase (i);
2603 fatal << _("programming error: ")
2604 << X_("unknown region type passed to Session::remove_region()")
2610 /* mark dirty because something has changed even if we didn't
2611 remove the region from the region list.
2617 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2621 boost::shared_ptr<AudioRegion>
2622 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2624 AudioRegionList::iterator i;
2625 boost::shared_ptr<AudioRegion> region;
2626 Glib::Mutex::Lock lm (region_lock);
2628 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2632 if (region->whole_file()) {
2634 if (child->source_equivalent (region)) {
2640 return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
2644 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2646 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2647 (*i)->get_region_list_equivalent_regions (region, result);
2651 Session::destroy_region (boost::shared_ptr<Region> region)
2653 boost::shared_ptr<AudioRegion> aregion;
2655 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2659 if (aregion->playlist()) {
2660 aregion->playlist()->destroy_region (region);
2663 vector<boost::shared_ptr<Source> > srcs;
2665 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2666 srcs.push_back (aregion->source (n));
2669 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2671 if ((*i).use_count() == 1) {
2672 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2675 (afs)->mark_for_remove ();
2678 (*i)->drop_references ();
2686 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2688 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2689 destroy_region (*i);
2695 Session::remove_last_capture ()
2697 list<boost::shared_ptr<Region> > r;
2699 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2701 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2702 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2705 r.insert (r.end(), l.begin(), l.end());
2710 destroy_regions (r);
2715 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2721 /* Source Management */
2724 Session::add_source (boost::shared_ptr<Source> source)
2726 boost::shared_ptr<AudioFileSource> afs;
2728 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2730 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2731 pair<AudioSourceList::iterator,bool> result;
2733 entry.first = source->id();
2737 Glib::Mutex::Lock lm (audio_source_lock);
2738 result = audio_sources.insert (entry);
2741 if (!result.second) {
2742 cerr << "\tNOT inserted ? " << result.second << endl;
2745 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2748 SourceAdded (source); /* EMIT SIGNAL */
2750 cerr << "\tNOT AUDIO FILE\n";
2755 Session::remove_source (boost::weak_ptr<Source> src)
2757 AudioSourceList::iterator i;
2758 boost::shared_ptr<Source> source = src.lock();
2761 cerr << "removing a source DEAD\n";
2763 cerr << "removing a source " << source->name () << endl;
2766 Glib::Mutex::Lock lm (audio_source_lock);
2768 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2769 audio_sources.erase (i);
2773 if (!_state_of_the_state & InCleanup) {
2775 /* save state so we don't end up with a session file
2776 referring to non-existent sources.
2779 save_state (_current_snapshot_name);
2782 SourceRemoved(source); /* EMIT SIGNAL */
2786 boost::shared_ptr<Source>
2787 Session::source_by_id (const PBD::ID& id)
2789 Glib::Mutex::Lock lm (audio_source_lock);
2790 AudioSourceList::iterator i;
2791 boost::shared_ptr<Source> source;
2793 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2797 /* XXX search MIDI or other searches here */
2803 Session::peak_path_from_audio_path (string audio_path) const
2808 res += PBD::basename_nosuffix (audio_path);
2815 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2818 string old_basename = PBD::basename_nosuffix (oldname);
2819 string new_legalized = legalize_for_path (newname);
2821 /* note: we know (or assume) the old path is already valid */
2825 /* destructive file sources have a name of the form:
2827 /path/to/Tnnnn-NAME(%[LR])?.wav
2829 the task here is to replace NAME with the new name.
2832 /* find last slash */
2836 string::size_type slash;
2837 string::size_type dash;
2839 if ((slash = path.find_last_of ('/')) == string::npos) {
2843 dir = path.substr (0, slash+1);
2845 /* '-' is not a legal character for the NAME part of the path */
2847 if ((dash = path.find_last_of ('-')) == string::npos) {
2851 prefix = path.substr (slash+1, dash-(slash+1));
2856 path += new_legalized;
2857 path += ".wav"; /* XXX gag me with a spoon */
2861 /* non-destructive file sources have a name of the form:
2863 /path/to/NAME-nnnnn(%[LR])?.wav
2865 the task here is to replace NAME with the new name.
2870 string::size_type slash;
2871 string::size_type dash;
2872 string::size_type postfix;
2874 /* find last slash */
2876 if ((slash = path.find_last_of ('/')) == string::npos) {
2880 dir = path.substr (0, slash+1);
2882 /* '-' is not a legal character for the NAME part of the path */
2884 if ((dash = path.find_last_of ('-')) == string::npos) {
2888 suffix = path.substr (dash+1);
2890 // Suffix is now everything after the dash. Now we need to eliminate
2891 // the nnnnn part, which is done by either finding a '%' or a '.'
2893 postfix = suffix.find_last_of ("%");
2894 if (postfix == string::npos) {
2895 postfix = suffix.find_last_of ('.');
2898 if (postfix != string::npos) {
2899 suffix = suffix.substr (postfix);
2901 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2905 const uint32_t limit = 10000;
2906 char buf[PATH_MAX+1];
2908 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2910 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2912 if (access (buf, F_OK) != 0) {
2920 error << "FATAL ERROR! Could not find a " << endl;
2929 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2933 char buf[PATH_MAX+1];
2934 const uint32_t limit = 10000;
2938 legalized = legalize_for_path (name);
2940 /* find a "version" of the file name that doesn't exist in
2941 any of the possible directories.
2944 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2946 vector<space_and_path>::iterator i;
2947 uint32_t existing = 0;
2949 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2953 spath += sound_dir_name;
2957 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2958 } else if (nchan == 2) {
2960 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2962 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2964 } else if (nchan < 26) {
2965 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2967 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2975 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2976 } else if (nchan == 2) {
2978 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2980 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2982 } else if (nchan < 26) {
2983 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2985 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2989 if (access (buf, F_OK) == 0) {
2994 if (existing == 0) {
2999 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3000 throw failed_constructor();
3004 /* we now have a unique name for the file, but figure out where to
3010 spath = discover_best_sound_dir ();
3012 string::size_type pos = foo.find_last_of ('/');
3014 if (pos == string::npos) {
3017 spath += foo.substr (pos + 1);
3023 boost::shared_ptr<AudioFileSource>
3024 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3026 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3027 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3030 /* Playlist management */
3033 Session::playlist_by_name (string name)
3035 Glib::Mutex::Lock lm (playlist_lock);
3036 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3037 if ((*i)->name() == name) {
3041 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3042 if ((*i)->name() == name) {
3050 Session::add_playlist (Playlist* playlist)
3052 if (playlist->hidden()) {
3057 Glib::Mutex::Lock lm (playlist_lock);
3058 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3059 playlists.insert (playlists.begin(), playlist);
3061 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3062 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
3068 PlaylistAdded (playlist); /* EMIT SIGNAL */
3072 Session::track_playlist (Playlist* pl, bool inuse)
3074 PlaylistList::iterator x;
3077 Glib::Mutex::Lock lm (playlist_lock);
3080 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3082 unused_playlists.insert (pl);
3084 if ((x = playlists.find (pl)) != playlists.end()) {
3085 playlists.erase (x);
3090 //cerr << "shifting playlist to used: " << pl->name() << endl;
3092 playlists.insert (pl);
3094 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3095 unused_playlists.erase (x);
3102 Session::remove_playlist (Playlist* playlist)
3104 if (_state_of_the_state & Deletion) {
3109 Glib::Mutex::Lock lm (playlist_lock);
3110 // cerr << "removing playlist: " << playlist->name() << endl;
3112 PlaylistList::iterator i;
3114 i = find (playlists.begin(), playlists.end(), playlist);
3116 if (i != playlists.end()) {
3117 playlists.erase (i);
3120 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3121 if (i != unused_playlists.end()) {
3122 unused_playlists.erase (i);
3129 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3133 Session::set_audition (boost::shared_ptr<Region> r)
3135 pending_audition_region = r;
3136 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3137 schedule_butler_transport_work ();
3141 Session::audition_playlist ()
3143 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3144 ev->region.reset ();
3149 Session::non_realtime_set_audition ()
3151 if (!pending_audition_region) {
3152 auditioner->audition_current_playlist ();
3154 auditioner->audition_region (pending_audition_region);
3155 pending_audition_region.reset ();
3157 AuditionActive (true); /* EMIT SIGNAL */
3161 Session::audition_region (boost::shared_ptr<Region> r)
3163 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3169 Session::cancel_audition ()
3171 if (auditioner->active()) {
3172 auditioner->cancel_audition ();
3173 AuditionActive (false); /* EMIT SIGNAL */
3178 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3180 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3184 Session::remove_empty_sounds ()
3186 PathScanner scanner;
3188 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3190 Glib::Mutex::Lock lm (audio_source_lock);
3192 regex_t compiled_tape_track_pattern;
3195 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3199 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3201 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3205 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3207 /* never remove files that appear to be a tape track */
3209 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3214 if (AudioFileSource::is_empty (*this, *(*i))) {
3216 unlink ((*i)->c_str());
3218 string peak_path = peak_path_from_audio_path (**i);
3219 unlink (peak_path.c_str());
3225 delete possible_audiofiles;
3229 Session::is_auditioning () const
3231 /* can be called before we have an auditioner object */
3233 return auditioner->active();
3240 Session::set_all_solo (bool yn)
3242 shared_ptr<RouteList> r = routes.reader ();
3244 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3245 if (!(*i)->hidden()) {
3246 (*i)->set_solo (yn, this);
3254 Session::set_all_mute (bool yn)
3256 shared_ptr<RouteList> r = routes.reader ();
3258 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3259 if (!(*i)->hidden()) {
3260 (*i)->set_mute (yn, this);
3268 Session::n_diskstreams () const
3272 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3274 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3275 if (!(*i)->hidden()) {
3283 Session::graph_reordered ()
3285 /* don't do this stuff if we are setting up connections
3286 from a set_state() call.
3289 if (_state_of_the_state & InitialConnecting) {
3295 /* force all diskstreams to update their capture offset values to
3296 reflect any changes in latencies within the graph.
3299 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3301 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3302 (*i)->set_capture_offset ();
3307 Session::record_disenable_all ()
3309 record_enable_change_all (false);
3313 Session::record_enable_all ()
3315 record_enable_change_all (true);
3319 Session::record_enable_change_all (bool yn)
3321 shared_ptr<RouteList> r = routes.reader ();
3323 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3326 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3327 at->set_record_enable (yn, this);
3331 /* since we don't keep rec-enable state, don't mark session dirty */
3335 Session::add_redirect (Redirect* redirect)
3339 PortInsert* port_insert;
3340 PluginInsert* plugin_insert;
3342 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3343 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3344 _port_inserts.insert (_port_inserts.begin(), port_insert);
3345 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3346 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3348 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3351 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3352 _sends.insert (_sends.begin(), send);
3354 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3358 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3364 Session::remove_redirect (Redirect* redirect)
3368 PortInsert* port_insert;
3369 PluginInsert* plugin_insert;
3371 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3372 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3373 _port_inserts.remove (port_insert);
3374 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3375 _plugin_inserts.remove (plugin_insert);
3377 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3380 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3381 _sends.remove (send);
3383 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3391 Session::available_capture_duration ()
3393 const double scale = 4096.0 / sizeof (Sample);
3395 if (_total_free_4k_blocks * scale > (double) max_frames) {
3399 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3403 Session::add_connection (ARDOUR::Connection* connection)
3406 Glib::Mutex::Lock guard (connection_lock);
3407 _connections.push_back (connection);
3410 ConnectionAdded (connection); /* EMIT SIGNAL */
3416 Session::remove_connection (ARDOUR::Connection* connection)
3418 bool removed = false;
3421 Glib::Mutex::Lock guard (connection_lock);
3422 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3424 if (i != _connections.end()) {
3425 _connections.erase (i);
3431 ConnectionRemoved (connection); /* EMIT SIGNAL */
3437 ARDOUR::Connection *
3438 Session::connection_by_name (string name) const
3440 Glib::Mutex::Lock lm (connection_lock);
3442 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3443 if ((*i)->name() == name) {
3452 Session::set_edit_mode (EditMode mode)
3457 Glib::Mutex::Lock lm (playlist_lock);
3459 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3460 (*i)->set_edit_mode (mode);
3465 ControlChanged (EditingMode); /* EMIT SIGNAL */
3469 Session::tempo_map_changed (Change ignored)
3476 Session::ensure_passthru_buffers (uint32_t howmany)
3478 while (howmany > _passthru_buffers.size()) {
3480 #ifdef NO_POSIX_MEMALIGN
3481 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3483 posix_memalign((void **)&p,16,current_block_size * 4);
3485 _passthru_buffers.push_back (p);
3489 #ifdef NO_POSIX_MEMALIGN
3490 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3492 posix_memalign((void **)&p,16,current_block_size * 4);
3494 memset (p, 0, sizeof (Sample) * current_block_size);
3495 _silent_buffers.push_back (p);
3499 #ifdef NO_POSIX_MEMALIGN
3500 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3502 posix_memalign((void **)&p,16,current_block_size * 4);
3504 memset (p, 0, sizeof (Sample) * current_block_size);
3505 _send_buffers.push_back (p);
3508 allocate_pan_automation_buffers (current_block_size, howmany, false);
3512 Session::next_send_name ()
3515 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3520 Session::next_insert_name ()
3523 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3527 /* Named Selection management */
3530 Session::named_selection_by_name (string name)
3532 Glib::Mutex::Lock lm (named_selection_lock);
3533 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3534 if ((*i)->name == name) {
3542 Session::add_named_selection (NamedSelection* named_selection)
3545 Glib::Mutex::Lock lm (named_selection_lock);
3546 named_selections.insert (named_selections.begin(), named_selection);
3551 NamedSelectionAdded (); /* EMIT SIGNAL */
3555 Session::remove_named_selection (NamedSelection* named_selection)
3557 bool removed = false;
3560 Glib::Mutex::Lock lm (named_selection_lock);
3562 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3564 if (i != named_selections.end()) {
3566 named_selections.erase (i);
3573 NamedSelectionRemoved (); /* EMIT SIGNAL */
3578 Session::reset_native_file_format ()
3580 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3582 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3583 (*i)->reset_write_sources (false);
3588 Session::route_name_unique (string n) const
3590 shared_ptr<RouteList> r = routes.reader ();
3592 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3593 if ((*i)->name() == n) {
3602 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3604 return fs->move_to_trash (dead_sound_dir_name);
3608 Session::n_playlists () const
3610 Glib::Mutex::Lock lm (playlist_lock);
3611 return playlists.size();
3615 Session::set_solo_model (SoloModel sm)
3617 if (sm != _solo_model) {
3619 ControlChanged (SoloingModel);
3625 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3627 if (!force && howmany <= _npan_buffers) {
3631 if (_pan_automation_buffer) {
3633 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3634 delete [] _pan_automation_buffer[i];
3637 delete [] _pan_automation_buffer;
3640 _pan_automation_buffer = new pan_t*[howmany];
3642 for (uint32_t i = 0; i < howmany; ++i) {
3643 _pan_automation_buffer[i] = new pan_t[nframes];
3646 _npan_buffers = howmany;
3650 Session::freeze (InterThreadInfo& itt)
3652 shared_ptr<RouteList> r = routes.reader ();
3654 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3658 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3659 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3670 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3671 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3675 boost::shared_ptr<AudioFileSource> fsource;
3677 char buf[PATH_MAX+1];
3680 jack_nframes_t position;
3681 jack_nframes_t this_chunk;
3682 jack_nframes_t to_do;
3683 vector<Sample*> buffers;
3685 // any bigger than this seems to cause stack overflows in called functions
3686 const jack_nframes_t chunk_size = (128 * 1024)/4;
3688 g_atomic_int_set (&processing_prohibited, 1);
3690 /* call tree *MUST* hold route_lock */
3692 if ((playlist = track.diskstream()->playlist()) == 0) {
3696 /* external redirects will be a problem */
3698 if (track.has_external_redirects()) {
3702 nchans = track.audio_diskstream()->n_channels();
3704 dir = discover_best_sound_dir ();
3706 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3708 for (x = 0; x < 99999; ++x) {
3709 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3710 if (access (buf, F_OK) != 0) {
3716 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3721 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3724 catch (failed_constructor& err) {
3725 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3729 srcs.push_back (fsource);
3732 /* XXX need to flush all redirects */
3737 /* create a set of reasonably-sized buffers */
3739 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3741 #ifdef NO_POSIX_MEMALIGN
3742 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3744 posix_memalign((void **)&b,16,chunk_size * 4);
3746 buffers.push_back (b);
3749 while (to_do && !itt.cancel) {
3751 this_chunk = min (to_do, chunk_size);
3753 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3758 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3759 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3762 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3768 start += this_chunk;
3769 to_do -= this_chunk;
3771 itt.progress = (float) (1.0 - ((double) to_do / len));
3780 xnow = localtime (&now);
3782 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3783 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3786 afs->update_header (position, *xnow, now);
3790 /* build peakfile for new source */
3792 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3793 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3795 afs->build_peaks ();
3804 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3805 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3808 afs->mark_for_remove ();
3811 (*src)->drop_references ();
3815 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3819 g_atomic_int_set (&processing_prohibited, 0);
3827 Session::get_silent_buffers (uint32_t howmany)
3829 for (uint32_t i = 0; i < howmany; ++i) {
3830 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3832 return _silent_buffers;
3836 Session::ntracks () const
3839 shared_ptr<RouteList> r = routes.reader ();
3841 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3842 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3851 Session::nbusses () const
3854 shared_ptr<RouteList> r = routes.reader ();
3856 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3857 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3866 Session::set_layer_model (LayerModel lm)
3868 if (lm != layer_model) {
3871 ControlChanged (LayeringModel);
3876 Session::set_xfade_model (CrossfadeModel xm)
3878 if (xm != xfade_model) {
3881 ControlChanged (CrossfadingModel);
3886 Session::handle_configuration_change (const char* parameter)
3888 if (!strcmp (parameter, "use-video-sync")) {
3889 if (_transport_speed == 0.0f) {
3890 waiting_for_sync_offset = true;
3896 Session::add_curve(Curve *curve)
3898 curves[curve->id()] = curve;
3902 Session::add_automation_list(AutomationList *al)
3904 automation_lists[al->id()] = al;