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 (false);
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 (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2995 if (existing == 0) {
3000 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3001 throw failed_constructor();
3005 /* we now have a unique name for the file, but figure out where to
3011 spath = discover_best_sound_dir ();
3013 string::size_type pos = foo.find_last_of ('/');
3015 if (pos == string::npos) {
3018 spath += foo.substr (pos + 1);
3024 boost::shared_ptr<AudioFileSource>
3025 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3027 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3028 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3031 /* Playlist management */
3034 Session::playlist_by_name (string name)
3036 Glib::Mutex::Lock lm (playlist_lock);
3037 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3038 if ((*i)->name() == name) {
3042 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3043 if ((*i)->name() == name) {
3051 Session::add_playlist (Playlist* playlist)
3053 if (playlist->hidden()) {
3058 Glib::Mutex::Lock lm (playlist_lock);
3059 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3060 playlists.insert (playlists.begin(), playlist);
3062 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3063 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
3069 PlaylistAdded (playlist); /* EMIT SIGNAL */
3073 Session::track_playlist (Playlist* pl, bool inuse)
3075 PlaylistList::iterator x;
3078 Glib::Mutex::Lock lm (playlist_lock);
3081 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3083 unused_playlists.insert (pl);
3085 if ((x = playlists.find (pl)) != playlists.end()) {
3086 playlists.erase (x);
3091 //cerr << "shifting playlist to used: " << pl->name() << endl;
3093 playlists.insert (pl);
3095 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3096 unused_playlists.erase (x);
3103 Session::remove_playlist (Playlist* playlist)
3105 if (_state_of_the_state & Deletion) {
3110 Glib::Mutex::Lock lm (playlist_lock);
3111 // cerr << "removing playlist: " << playlist->name() << endl;
3113 PlaylistList::iterator i;
3115 i = find (playlists.begin(), playlists.end(), playlist);
3117 if (i != playlists.end()) {
3118 playlists.erase (i);
3121 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3122 if (i != unused_playlists.end()) {
3123 unused_playlists.erase (i);
3130 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3134 Session::set_audition (boost::shared_ptr<Region> r)
3136 pending_audition_region = r;
3137 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3138 schedule_butler_transport_work ();
3142 Session::audition_playlist ()
3144 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3145 ev->region.reset ();
3150 Session::non_realtime_set_audition ()
3152 if (!pending_audition_region) {
3153 auditioner->audition_current_playlist ();
3155 auditioner->audition_region (pending_audition_region);
3156 pending_audition_region.reset ();
3158 AuditionActive (true); /* EMIT SIGNAL */
3162 Session::audition_region (boost::shared_ptr<Region> r)
3164 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3170 Session::cancel_audition ()
3172 if (auditioner->active()) {
3173 auditioner->cancel_audition ();
3174 AuditionActive (false); /* EMIT SIGNAL */
3179 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3181 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3185 Session::remove_empty_sounds ()
3187 PathScanner scanner;
3189 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3191 Glib::Mutex::Lock lm (audio_source_lock);
3193 regex_t compiled_tape_track_pattern;
3196 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3200 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3202 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3206 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3208 /* never remove files that appear to be a tape track */
3210 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3215 if (AudioFileSource::is_empty (*this, *(*i))) {
3217 unlink ((*i)->c_str());
3219 string peak_path = peak_path_from_audio_path (**i);
3220 unlink (peak_path.c_str());
3226 delete possible_audiofiles;
3230 Session::is_auditioning () const
3232 /* can be called before we have an auditioner object */
3234 return auditioner->active();
3241 Session::set_all_solo (bool yn)
3243 shared_ptr<RouteList> r = routes.reader ();
3245 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3246 if (!(*i)->hidden()) {
3247 (*i)->set_solo (yn, this);
3255 Session::set_all_mute (bool yn)
3257 shared_ptr<RouteList> r = routes.reader ();
3259 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3260 if (!(*i)->hidden()) {
3261 (*i)->set_mute (yn, this);
3269 Session::n_diskstreams () const
3273 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3275 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3276 if (!(*i)->hidden()) {
3284 Session::graph_reordered ()
3286 /* don't do this stuff if we are setting up connections
3287 from a set_state() call.
3290 if (_state_of_the_state & InitialConnecting) {
3296 /* force all diskstreams to update their capture offset values to
3297 reflect any changes in latencies within the graph.
3300 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3302 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3303 (*i)->set_capture_offset ();
3308 Session::record_disenable_all ()
3310 record_enable_change_all (false);
3314 Session::record_enable_all ()
3316 record_enable_change_all (true);
3320 Session::record_enable_change_all (bool yn)
3322 shared_ptr<RouteList> r = routes.reader ();
3324 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3327 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3328 at->set_record_enable (yn, this);
3332 /* since we don't keep rec-enable state, don't mark session dirty */
3336 Session::add_redirect (Redirect* redirect)
3340 PortInsert* port_insert;
3341 PluginInsert* plugin_insert;
3343 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3344 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3345 _port_inserts.insert (_port_inserts.begin(), port_insert);
3346 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3347 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3349 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3352 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3353 _sends.insert (_sends.begin(), send);
3355 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3359 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3365 Session::remove_redirect (Redirect* redirect)
3369 PortInsert* port_insert;
3370 PluginInsert* plugin_insert;
3372 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3373 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3374 _port_inserts.remove (port_insert);
3375 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3376 _plugin_inserts.remove (plugin_insert);
3378 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3381 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3382 _sends.remove (send);
3384 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3392 Session::available_capture_duration ()
3394 const double scale = 4096.0 / sizeof (Sample);
3396 if (_total_free_4k_blocks * scale > (double) max_frames) {
3400 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3404 Session::add_connection (ARDOUR::Connection* connection)
3407 Glib::Mutex::Lock guard (connection_lock);
3408 _connections.push_back (connection);
3411 ConnectionAdded (connection); /* EMIT SIGNAL */
3417 Session::remove_connection (ARDOUR::Connection* connection)
3419 bool removed = false;
3422 Glib::Mutex::Lock guard (connection_lock);
3423 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3425 if (i != _connections.end()) {
3426 _connections.erase (i);
3432 ConnectionRemoved (connection); /* EMIT SIGNAL */
3438 ARDOUR::Connection *
3439 Session::connection_by_name (string name) const
3441 Glib::Mutex::Lock lm (connection_lock);
3443 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3444 if ((*i)->name() == name) {
3453 Session::set_edit_mode (EditMode mode)
3458 Glib::Mutex::Lock lm (playlist_lock);
3460 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3461 (*i)->set_edit_mode (mode);
3466 ControlChanged (EditingMode); /* EMIT SIGNAL */
3470 Session::tempo_map_changed (Change ignored)
3477 Session::ensure_passthru_buffers (uint32_t howmany)
3479 while (howmany > _passthru_buffers.size()) {
3481 #ifdef NO_POSIX_MEMALIGN
3482 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3484 posix_memalign((void **)&p,16,current_block_size * 4);
3486 _passthru_buffers.push_back (p);
3490 #ifdef NO_POSIX_MEMALIGN
3491 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3493 posix_memalign((void **)&p,16,current_block_size * 4);
3495 memset (p, 0, sizeof (Sample) * current_block_size);
3496 _silent_buffers.push_back (p);
3500 #ifdef NO_POSIX_MEMALIGN
3501 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3503 posix_memalign((void **)&p,16,current_block_size * 4);
3505 memset (p, 0, sizeof (Sample) * current_block_size);
3506 _send_buffers.push_back (p);
3509 allocate_pan_automation_buffers (current_block_size, howmany, false);
3513 Session::next_send_name ()
3516 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3521 Session::next_insert_name ()
3524 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3528 /* Named Selection management */
3531 Session::named_selection_by_name (string name)
3533 Glib::Mutex::Lock lm (named_selection_lock);
3534 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3535 if ((*i)->name == name) {
3543 Session::add_named_selection (NamedSelection* named_selection)
3546 Glib::Mutex::Lock lm (named_selection_lock);
3547 named_selections.insert (named_selections.begin(), named_selection);
3552 NamedSelectionAdded (); /* EMIT SIGNAL */
3556 Session::remove_named_selection (NamedSelection* named_selection)
3558 bool removed = false;
3561 Glib::Mutex::Lock lm (named_selection_lock);
3563 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3565 if (i != named_selections.end()) {
3567 named_selections.erase (i);
3574 NamedSelectionRemoved (); /* EMIT SIGNAL */
3579 Session::reset_native_file_format ()
3581 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3583 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3584 (*i)->reset_write_sources (false);
3589 Session::route_name_unique (string n) const
3591 shared_ptr<RouteList> r = routes.reader ();
3593 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3594 if ((*i)->name() == n) {
3603 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3605 return fs->move_to_trash (dead_sound_dir_name);
3609 Session::n_playlists () const
3611 Glib::Mutex::Lock lm (playlist_lock);
3612 return playlists.size();
3616 Session::set_solo_model (SoloModel sm)
3618 if (sm != _solo_model) {
3620 ControlChanged (SoloingModel);
3626 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3628 if (!force && howmany <= _npan_buffers) {
3632 if (_pan_automation_buffer) {
3634 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3635 delete [] _pan_automation_buffer[i];
3638 delete [] _pan_automation_buffer;
3641 _pan_automation_buffer = new pan_t*[howmany];
3643 for (uint32_t i = 0; i < howmany; ++i) {
3644 _pan_automation_buffer[i] = new pan_t[nframes];
3647 _npan_buffers = howmany;
3651 Session::freeze (InterThreadInfo& itt)
3653 shared_ptr<RouteList> r = routes.reader ();
3655 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3659 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3660 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3671 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3672 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3676 boost::shared_ptr<AudioFileSource> fsource;
3678 char buf[PATH_MAX+1];
3681 jack_nframes_t position;
3682 jack_nframes_t this_chunk;
3683 jack_nframes_t to_do;
3684 vector<Sample*> buffers;
3686 // any bigger than this seems to cause stack overflows in called functions
3687 const jack_nframes_t chunk_size = (128 * 1024)/4;
3689 g_atomic_int_set (&processing_prohibited, 1);
3691 /* call tree *MUST* hold route_lock */
3693 if ((playlist = track.diskstream()->playlist()) == 0) {
3697 /* external redirects will be a problem */
3699 if (track.has_external_redirects()) {
3703 nchans = track.audio_diskstream()->n_channels();
3705 dir = discover_best_sound_dir ();
3707 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3709 for (x = 0; x < 99999; ++x) {
3710 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3711 if (access (buf, F_OK) != 0) {
3717 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3722 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3725 catch (failed_constructor& err) {
3726 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3730 srcs.push_back (fsource);
3733 /* XXX need to flush all redirects */
3738 /* create a set of reasonably-sized buffers */
3740 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3742 #ifdef NO_POSIX_MEMALIGN
3743 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3745 posix_memalign((void **)&b,16,chunk_size * 4);
3747 buffers.push_back (b);
3750 while (to_do && !itt.cancel) {
3752 this_chunk = min (to_do, chunk_size);
3754 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3759 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3760 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3763 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3769 start += this_chunk;
3770 to_do -= this_chunk;
3772 itt.progress = (float) (1.0 - ((double) to_do / len));
3781 xnow = localtime (&now);
3783 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3784 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3787 afs->update_header (position, *xnow, now);
3791 /* build peakfile for new source */
3793 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3794 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3796 afs->build_peaks ();
3805 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3806 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3809 afs->mark_for_remove ();
3812 (*src)->drop_references ();
3816 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3820 g_atomic_int_set (&processing_prohibited, 0);
3828 Session::get_silent_buffers (uint32_t howmany)
3830 for (uint32_t i = 0; i < howmany; ++i) {
3831 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3833 return _silent_buffers;
3837 Session::ntracks () const
3840 shared_ptr<RouteList> r = routes.reader ();
3842 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3843 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3852 Session::nbusses () const
3855 shared_ptr<RouteList> r = routes.reader ();
3857 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3858 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3867 Session::set_layer_model (LayerModel lm)
3869 if (lm != layer_model) {
3872 ControlChanged (LayeringModel);
3877 Session::set_xfade_model (CrossfadeModel xm)
3879 if (xm != xfade_model) {
3882 ControlChanged (CrossfadingModel);
3887 Session::handle_configuration_change (const char* parameter)
3889 if (!strcmp (parameter, "use-video-sync")) {
3890 if (_transport_speed == 0.0f) {
3891 waiting_for_sync_offset = true;
3897 Session::add_curve(Curve *curve)
3899 curves[curve->id()] = curve;
3903 Session::add_automation_list(AutomationList *al)
3905 automation_lists[al->id()] = al;