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::sound_dir_name = X_("sounds");
85 const char* Session::tape_dir_name = X_("tapes");
86 const char* Session::peak_dir_name = X_("peaks");
87 const char* Session::dead_sound_dir_name = X_("dead_sounds");
89 Session::compute_peak_t Session::compute_peak = 0;
90 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
91 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
92 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
94 sigc::signal<int> Session::AskAboutPendingState;
95 sigc::signal<void> Session::SMPTEOffsetChanged;
96 sigc::signal<void> Session::SendFeedback;
100 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
103 char buf[PATH_MAX+1];
107 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
108 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
114 /* check to see if it exists, and what it is */
116 if (stat (str.c_str(), &statbuf)) {
117 if (errno == ENOENT) {
120 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
128 /* it exists, so it must either be the name
129 of the directory, or the name of the statefile
133 if (S_ISDIR (statbuf.st_mode)) {
135 string::size_type slash = str.find_last_of ('/');
137 if (slash == string::npos) {
139 /* a subdirectory of cwd, so statefile should be ... */
145 tmp += _statefile_suffix;
149 if (stat (tmp.c_str(), &statbuf)) {
150 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
160 /* some directory someplace in the filesystem.
161 the snapshot name is the directory name
166 snapshot = str.substr (slash+1);
170 } else if (S_ISREG (statbuf.st_mode)) {
172 string::size_type slash = str.find_last_of ('/');
173 string::size_type suffix;
175 /* remove the suffix */
177 if (slash != string::npos) {
178 snapshot = str.substr (slash+1);
183 suffix = snapshot.find (_statefile_suffix);
185 if (suffix == string::npos) {
186 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
192 snapshot = snapshot.substr (0, suffix);
194 if (slash == string::npos) {
196 /* we must be in the directory where the
197 statefile lives. get it using cwd().
200 char cwd[PATH_MAX+1];
202 if (getcwd (cwd, sizeof (cwd)) == 0) {
203 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
212 /* full path to the statefile */
214 path = str.substr (0, slash);
219 /* what type of file is it? */
220 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
226 /* its the name of a new directory. get the name
230 string::size_type slash = str.find_last_of ('/');
232 if (slash == string::npos) {
234 /* no slash, just use the name, but clean it up */
236 path = legalize_for_path (str);
242 snapshot = str.substr (slash+1);
249 Session::Session (AudioEngine &eng,
251 string snapshot_name,
252 string* mix_template)
255 _mmc_port (default_mmc_port),
256 _mtc_port (default_mtc_port),
257 _midi_port (default_midi_port),
258 pending_events (2048),
259 midi_requests (128), // the size of this should match the midi request pool size
260 diskstreams (new DiskstreamList),
261 routes (new RouteList),
262 auditioner ((Auditioner*) 0),
268 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
270 n_physical_outputs = _engine.n_physical_outputs();
271 n_physical_inputs = _engine.n_physical_inputs();
273 first_stage_init (fullpath, snapshot_name);
275 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
276 cerr << "create failed\n";
277 throw failed_constructor ();
280 if (second_stage_init (new_session)) {
281 cerr << "2nd state failed\n";
282 throw failed_constructor ();
285 store_recent_sessions(_name, _path);
287 bool was_dirty = dirty();
289 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
292 DirtyChanged (); /* EMIT SIGNAL */
296 Session::Session (AudioEngine &eng,
298 string snapshot_name,
299 AutoConnectOption input_ac,
300 AutoConnectOption output_ac,
301 uint32_t control_out_channels,
302 uint32_t master_out_channels,
303 uint32_t requested_physical_in,
304 uint32_t requested_physical_out,
305 jack_nframes_t initial_length)
308 _mmc_port (default_mmc_port),
309 _mtc_port (default_mtc_port),
310 _midi_port (default_midi_port),
311 pending_events (2048),
313 diskstreams (new DiskstreamList),
314 routes (new RouteList),
320 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
322 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
323 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
325 first_stage_init (fullpath, snapshot_name);
327 if (create (new_session, 0, initial_length)) {
328 throw failed_constructor ();
331 if (control_out_channels) {
332 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
339 if (master_out_channels) {
340 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
346 /* prohibit auto-connect to master, because there isn't one */
347 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
350 input_auto_connect = input_ac;
351 output_auto_connect = output_ac;
353 if (second_stage_init (new_session)) {
354 throw failed_constructor ();
357 store_recent_sessions(_name, _path);
359 bool was_dirty = dirty ();
361 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
364 DirtyChanged (); /* EMIT SIGNAL */
370 /* if we got to here, leaving pending capture state around
374 remove_pending_capture_state ();
376 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
377 _engine.remove_session ();
379 GoingAway (); /* EMIT SIGNAL */
385 /* clear history so that no references to objects are held any more */
389 /* clear state tree so that no references to objects are held any more */
395 terminate_butler_thread ();
396 terminate_midi_thread ();
398 if (click_data && click_data != default_click) {
399 delete [] click_data;
402 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
403 delete [] click_emphasis_data;
408 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
412 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
416 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
420 AudioDiskstream::free_working_buffers();
422 #undef TRACK_DESTRUCTION
423 #ifdef TRACK_DESTRUCTION
424 cerr << "delete named selections\n";
425 #endif /* TRACK_DESTRUCTION */
426 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
427 NamedSelectionList::iterator tmp;
436 #ifdef TRACK_DESTRUCTION
437 cerr << "delete playlists\n";
438 #endif /* TRACK_DESTRUCTION */
439 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
440 PlaylistList::iterator tmp;
450 #ifdef TRACK_DESTRUCTION
451 cerr << "delete audio regions\n";
452 #endif /* TRACK_DESTRUCTION */
454 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
455 i->second->drop_references ();
458 audio_regions.clear ();
460 #ifdef TRACK_DESTRUCTION
461 cerr << "delete routes\n";
462 #endif /* TRACK_DESTRUCTION */
464 RCUWriter<RouteList> writer (routes);
465 boost::shared_ptr<RouteList> r = writer.get_copy ();
466 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
467 (*i)->drop_references ();
470 /* writer goes out of scope and updates master */
475 #ifdef TRACK_DESTRUCTION
476 cerr << "delete diskstreams\n";
477 #endif /* TRACK_DESTRUCTION */
479 RCUWriter<DiskstreamList> dwriter (diskstreams);
480 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
481 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
482 (*i)->drop_references ();
486 diskstreams.flush ();
488 #ifdef TRACK_DESTRUCTION
489 cerr << "delete audio sources\n";
490 #endif /* TRACK_DESTRUCTION */
491 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
492 AudioSourceList::iterator tmp;
497 i->second->drop_references ();
502 audio_sources.clear ();
504 #ifdef TRACK_DESTRUCTION
505 cerr << "delete mix groups\n";
506 #endif /* TRACK_DESTRUCTION */
507 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
508 list<RouteGroup*>::iterator tmp;
518 #ifdef TRACK_DESTRUCTION
519 cerr << "delete edit groups\n";
520 #endif /* TRACK_DESTRUCTION */
521 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
522 list<RouteGroup*>::iterator tmp;
532 #ifdef TRACK_DESTRUCTION
533 cerr << "delete connections\n";
534 #endif /* TRACK_DESTRUCTION */
535 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
536 ConnectionList::iterator tmp;
546 if (butler_mixdown_buffer) {
547 delete [] butler_mixdown_buffer;
550 if (butler_gain_buffer) {
551 delete [] butler_gain_buffer;
554 Crossfade::set_buffer_size (0);
562 Session::set_worst_io_latencies ()
564 _worst_output_latency = 0;
565 _worst_input_latency = 0;
567 if (!_engine.connected()) {
571 boost::shared_ptr<RouteList> r = routes.reader ();
573 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
574 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
575 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
580 Session::when_engine_running ()
582 string first_physical_output;
584 /* we don't want to run execute this again */
586 first_time_running.disconnect ();
588 set_block_size (_engine.frames_per_cycle());
589 set_frame_rate (_engine.frame_rate());
591 /* every time we reconnect, recompute worst case output latencies */
593 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
595 if (synced_to_jack()) {
596 _engine.transport_stop ();
599 if (Config->get_jack_time_master()) {
600 _engine.transport_locate (_transport_frame);
608 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
610 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
612 /* existing state for Click */
614 if (_click_io->set_state (*child->children().front()) == 0) {
616 _clicking = click_requested;
620 error << _("could not setup Click I/O") << endmsg;
626 /* default state for Click */
628 first_physical_output = _engine.get_nth_physical_output (0);
630 if (first_physical_output.length()) {
631 if (_click_io->add_output_port (first_physical_output, this)) {
632 // relax, even though its an error
634 _clicking = click_requested;
640 catch (failed_constructor& err) {
641 error << _("cannot setup Click I/O") << endmsg;
644 set_worst_io_latencies ();
647 ControlChanged (Clicking); /* EMIT SIGNAL */
650 if (auditioner == 0) {
652 /* we delay creating the auditioner till now because
653 it makes its own connections to ports named
654 in the ARDOUR_RC config file. the engine has
655 to be running for this to work.
659 auditioner.reset (new Auditioner (*this));
662 catch (failed_constructor& err) {
663 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
667 /* Create a set of Connection objects that map
668 to the physical outputs currently available
673 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
675 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
677 Connection* c = new OutputConnection (buf, true);
680 c->add_connection (0, _engine.get_nth_physical_output (np));
685 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
687 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
689 Connection* c = new InputConnection (buf, true);
692 c->add_connection (0, _engine.get_nth_physical_input (np));
699 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
701 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
703 Connection* c = new OutputConnection (buf, true);
707 c->add_connection (0, _engine.get_nth_physical_output (np));
708 c->add_connection (1, _engine.get_nth_physical_output (np+1));
713 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
715 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
717 Connection* c = new InputConnection (buf, true);
721 c->add_connection (0, _engine.get_nth_physical_input (np));
722 c->add_connection (1, _engine.get_nth_physical_input (np+1));
731 /* create master/control ports */
736 /* force the master to ignore any later call to this */
738 if (_master_out->pending_state_node) {
739 _master_out->ports_became_legal();
742 /* no panner resets till we are through */
744 _master_out->defer_pan_reset ();
746 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
747 if (_master_out->add_input_port ("", this)) {
748 error << _("cannot setup master inputs")
754 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
755 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
756 error << _("cannot setup master outputs")
763 _master_out->allow_pan_reset ();
767 Connection* c = new OutputConnection (_("Master Out"), true);
769 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
771 c->add_connection ((int) n, _master_out->input(n)->name());
778 /* catch up on send+insert cnts */
782 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
785 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
786 if (id > insert_cnt) {
794 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
797 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
804 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
806 /* hook us up to the engine */
808 _engine.set_session (this);
813 osc->set_session (*this);
816 _state_of_the_state = Clean;
818 DirtyChanged (); /* EMIT SIGNAL */
822 Session::hookup_io ()
824 /* stop graph reordering notifications from
825 causing resorts, etc.
828 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
830 /* Tell all IO objects to create their ports */
837 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
838 if (_control_out->add_input_port ("", this)) {
839 error << _("cannot setup control inputs")
845 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
846 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
847 error << _("cannot set up master outputs")
855 /* Tell all IO objects to connect themselves together */
857 IO::enable_connecting ();
859 /* Now reset all panners */
861 IO::reset_panners ();
863 /* Anyone who cares about input state, wake up and do something */
865 IOConnectionsComplete (); /* EMIT SIGNAL */
867 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
869 /* now handle the whole enchilada as if it was one
875 /* update mixer solo state */
881 Session::playlist_length_changed (Playlist* pl)
883 /* we can't just increase end_location->end() if pl->get_maximum_extent()
884 if larger. if the playlist used to be the longest playlist,
885 and its now shorter, we have to decrease end_location->end(). hence,
886 we have to iterate over all diskstreams and check the
887 playlists currently in use.
893 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
897 if ((playlist = dstream->playlist()) != 0) {
898 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
901 /* see comment in playlist_length_changed () */
906 Session::record_enabling_legal () const
908 /* this used to be in here, but survey says.... we don't need to restrict it */
909 // if (record_status() == Recording) {
920 Session::set_auto_play (bool yn)
922 if (auto_play != yn) {
925 ControlChanged (AutoPlay);
930 Session::set_auto_return (bool yn)
932 if (auto_return != yn) {
935 ControlChanged (AutoReturn);
940 Session::set_crossfades_active (bool yn)
942 if (crossfades_active != yn) {
943 crossfades_active = yn;
945 ControlChanged (CrossFadesActive);
950 Session::set_do_not_record_plugins (bool yn)
952 if (do_not_record_plugins != yn) {
953 do_not_record_plugins = yn;
955 ControlChanged (RecordingPlugins);
960 Session::set_auto_input (bool yn)
962 if (auto_input != yn) {
965 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
966 /* auto-input only makes a difference if we're rolling */
968 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
970 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
971 if ((*i)->record_enabled ()) {
972 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
973 (*i)->monitor_input (!auto_input);
979 ControlChanged (AutoInput);
984 Session::reset_input_monitor_state ()
986 if (transport_rolling()) {
988 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
990 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
991 if ((*i)->record_enabled ()) {
992 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
993 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
997 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
999 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1000 if ((*i)->record_enabled ()) {
1001 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1002 (*i)->monitor_input (Config->get_use_hardware_monitoring());
1010 Session::set_input_auto_connect (bool yn)
1013 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
1015 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1021 Session::get_input_auto_connect () const
1023 return (input_auto_connect & AutoConnectPhysical);
1027 Session::set_output_auto_connect (AutoConnectOption aco)
1029 output_auto_connect = aco;
1034 Session::auto_punch_start_changed (Location* location)
1036 replace_event (Event::PunchIn, location->start());
1038 if (get_record_enabled() && get_punch_in()) {
1039 /* capture start has been changed, so save new pending state */
1040 save_state ("", true);
1045 Session::auto_punch_end_changed (Location* location)
1047 jack_nframes_t when_to_stop = location->end();
1048 // when_to_stop += _worst_output_latency + _worst_input_latency;
1049 replace_event (Event::PunchOut, when_to_stop);
1053 Session::auto_punch_changed (Location* location)
1055 jack_nframes_t when_to_stop = location->end();
1057 replace_event (Event::PunchIn, location->start());
1058 //when_to_stop += _worst_output_latency + _worst_input_latency;
1059 replace_event (Event::PunchOut, when_to_stop);
1063 Session::auto_loop_changed (Location* location)
1065 replace_event (Event::AutoLoop, location->end(), location->start());
1067 if (transport_rolling() && get_auto_loop()) {
1069 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1071 if (_transport_frame > location->end()) {
1072 // relocate to beginning of loop
1073 clear_events (Event::LocateRoll);
1075 request_locate (location->start(), true);
1078 else if (seamless_loop && !loop_changing) {
1080 // schedule a locate-roll to refill the diskstreams at the
1081 // previous loop end
1082 loop_changing = true;
1084 if (location->end() > last_loopend) {
1085 clear_events (Event::LocateRoll);
1086 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1093 last_loopend = location->end();
1098 Session::set_auto_punch_location (Location* location)
1102 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1103 auto_punch_start_changed_connection.disconnect();
1104 auto_punch_end_changed_connection.disconnect();
1105 auto_punch_changed_connection.disconnect();
1106 existing->set_auto_punch (false, this);
1107 remove_event (existing->start(), Event::PunchIn);
1108 clear_events (Event::PunchOut);
1109 auto_punch_location_changed (0);
1114 if (location == 0) {
1118 if (location->end() <= location->start()) {
1119 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1123 auto_punch_start_changed_connection.disconnect();
1124 auto_punch_end_changed_connection.disconnect();
1125 auto_punch_changed_connection.disconnect();
1127 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1128 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1129 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1131 location->set_auto_punch (true, this);
1132 auto_punch_location_changed (location);
1136 Session::set_punch_in (bool yn)
1138 if (punch_in == yn) {
1144 if ((location = _locations.auto_punch_location()) != 0) {
1145 if ((punch_in = yn) == true) {
1146 replace_event (Event::PunchIn, location->start());
1148 remove_event (location->start(), Event::PunchIn);
1153 ControlChanged (PunchIn); /* EMIT SIGNAL */
1157 Session::set_punch_out (bool yn)
1159 if (punch_out == yn) {
1165 if ((location = _locations.auto_punch_location()) != 0) {
1166 if ((punch_out = yn) == true) {
1167 replace_event (Event::PunchOut, location->end());
1169 clear_events (Event::PunchOut);
1174 ControlChanged (PunchOut); /* EMIT SIGNAL */
1178 Session::set_auto_loop_location (Location* location)
1182 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1183 auto_loop_start_changed_connection.disconnect();
1184 auto_loop_end_changed_connection.disconnect();
1185 auto_loop_changed_connection.disconnect();
1186 existing->set_auto_loop (false, this);
1187 remove_event (existing->end(), Event::AutoLoop);
1188 auto_loop_location_changed (0);
1193 if (location == 0) {
1197 if (location->end() <= location->start()) {
1198 error << _("Session: you can't use a mark for auto loop") << endmsg;
1202 last_loopend = location->end();
1204 auto_loop_start_changed_connection.disconnect();
1205 auto_loop_end_changed_connection.disconnect();
1206 auto_loop_changed_connection.disconnect();
1208 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1209 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1210 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1212 location->set_auto_loop (true, this);
1213 auto_loop_location_changed (location);
1217 Session::locations_added (Location* ignored)
1223 Session::locations_changed ()
1225 _locations.apply (*this, &Session::handle_locations_changed);
1229 Session::handle_locations_changed (Locations::LocationList& locations)
1231 Locations::LocationList::iterator i;
1233 bool set_loop = false;
1234 bool set_punch = false;
1236 for (i = locations.begin(); i != locations.end(); ++i) {
1240 if (location->is_auto_punch()) {
1241 set_auto_punch_location (location);
1244 if (location->is_auto_loop()) {
1245 set_auto_loop_location (location);
1252 set_auto_loop_location (0);
1255 set_auto_punch_location (0);
1262 Session::enable_record ()
1264 /* XXX really atomic compare+swap here */
1265 if (g_atomic_int_get (&_record_status) != Recording) {
1266 g_atomic_int_set (&_record_status, Recording);
1267 _last_record_location = _transport_frame;
1268 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1270 if (Config->get_use_hardware_monitoring() && auto_input) {
1271 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1272 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1273 if ((*i)->record_enabled ()) {
1274 (*i)->monitor_input (true);
1279 RecordStateChanged ();
1284 Session::disable_record (bool rt_context, bool force)
1288 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1290 if (!Config->get_latched_record_enable () || force) {
1291 g_atomic_int_set (&_record_status, Disabled);
1293 if (rs == Recording) {
1294 g_atomic_int_set (&_record_status, Enabled);
1298 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1300 if (Config->get_use_hardware_monitoring() && auto_input) {
1301 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1303 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1304 if ((*i)->record_enabled ()) {
1305 (*i)->monitor_input (false);
1310 RecordStateChanged (); /* emit signal */
1313 remove_pending_capture_state ();
1319 Session::step_back_from_record ()
1321 g_atomic_int_set (&_record_status, Enabled);
1323 if (Config->get_use_hardware_monitoring()) {
1324 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1326 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1327 if (auto_input && (*i)->record_enabled ()) {
1328 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1329 (*i)->monitor_input (false);
1336 Session::maybe_enable_record ()
1338 g_atomic_int_set (&_record_status, Enabled);
1340 /* XXX this save should really happen in another thread. its needed so that
1341 pending capture state can be recovered if we crash.
1344 save_state ("", true);
1346 if (_transport_speed) {
1351 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1352 RecordStateChanged (); /* EMIT SIGNAL */
1359 Session::audible_frame () const
1362 jack_nframes_t offset;
1365 /* the first of these two possible settings for "offset"
1366 mean that the audible frame is stationary until
1367 audio emerges from the latency compensation
1370 the second means that the audible frame is stationary
1371 until audio would emerge from a physical port
1372 in the absence of any plugin latency compensation
1375 offset = _worst_output_latency;
1377 if (offset > current_block_size) {
1378 offset -= current_block_size;
1380 /* XXX is this correct? if we have no external
1381 physical connections and everything is internal
1382 then surely this is zero? still, how
1383 likely is that anyway?
1385 offset = current_block_size;
1388 if (synced_to_jack()) {
1389 tf = _engine.transport_frame();
1391 tf = _transport_frame;
1394 if (_transport_speed == 0) {
1404 if (!non_realtime_work_pending()) {
1408 /* take latency into account */
1417 Session::set_frame_rate (jack_nframes_t frames_per_second)
1419 /** \fn void Session::set_frame_size(jack_nframes_t)
1420 the AudioEngine object that calls this guarantees
1421 that it will not be called while we are also in
1422 ::process(). Its fine to do things that block
1426 _current_frame_rate = frames_per_second;
1427 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1429 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1431 // XXX we need some equivalent to this, somehow
1432 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1436 /* XXX need to reset/reinstantiate all LADSPA plugins */
1440 Session::set_block_size (jack_nframes_t nframes)
1442 /* the AudioEngine guarantees
1443 that it will not be called while we are also in
1444 ::process(). It is therefore fine to do things that block
1449 vector<Sample*>::iterator i;
1452 current_block_size = nframes;
1454 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1458 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1462 _passthru_buffers.clear ();
1463 _silent_buffers.clear ();
1465 ensure_passthru_buffers (np);
1467 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1471 #ifdef NO_POSIX_MEMALIGN
1472 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1474 posix_memalign((void **)&buf,16,current_block_size * 4);
1478 memset (*i, 0, sizeof (Sample) * current_block_size);
1482 if (_gain_automation_buffer) {
1483 delete [] _gain_automation_buffer;
1485 _gain_automation_buffer = new gain_t[nframes];
1487 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1489 boost::shared_ptr<RouteList> r = routes.reader ();
1491 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1492 (*i)->set_block_size (nframes);
1495 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1496 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1497 (*i)->set_block_size (nframes);
1500 set_worst_io_latencies ();
1505 Session::set_default_fade (float steepness, float fade_msecs)
1508 jack_nframes_t fade_frames;
1510 /* Don't allow fade of less 1 frame */
1512 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1519 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1523 default_fade_msecs = fade_msecs;
1524 default_fade_steepness = steepness;
1527 // jlc, WTF is this!
1528 Glib::RWLock::ReaderLock lm (route_lock);
1529 AudioRegion::set_default_fade (steepness, fade_frames);
1534 /* XXX have to do this at some point */
1535 /* foreach region using default fade, reset, then
1536 refill_all_diskstream_buffers ();
1541 struct RouteSorter {
1542 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1543 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1545 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1548 if (r1->fed_by.empty()) {
1549 if (r2->fed_by.empty()) {
1550 /* no ardour-based connections inbound to either route. just use signal order */
1551 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1553 /* r2 has connections, r1 does not; run r1 early */
1557 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1564 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1566 shared_ptr<Route> r2;
1568 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1569 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1573 /* make a copy of the existing list of routes that feed r1 */
1575 set<shared_ptr<Route> > existing = r1->fed_by;
1577 /* for each route that feeds r1, recurse, marking it as feeding
1581 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1584 /* r2 is a route that feeds r1 which somehow feeds base. mark
1585 base as being fed by r2
1588 rbase->fed_by.insert (r2);
1592 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1596 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1600 /* now recurse, so that we can mark base as being fed by
1601 all routes that feed r2
1604 trace_terminal (r2, rbase);
1611 Session::resort_routes ()
1613 /* don't do anything here with signals emitted
1614 by Routes while we are being destroyed.
1617 if (_state_of_the_state & Deletion) {
1624 RCUWriter<RouteList> writer (routes);
1625 shared_ptr<RouteList> r = writer.get_copy ();
1626 resort_routes_using (r);
1627 /* writer goes out of scope and forces update */
1632 Session::resort_routes_using (shared_ptr<RouteList> r)
1634 RouteList::iterator i, j;
1636 for (i = r->begin(); i != r->end(); ++i) {
1638 (*i)->fed_by.clear ();
1640 for (j = r->begin(); j != r->end(); ++j) {
1642 /* although routes can feed themselves, it will
1643 cause an endless recursive descent if we
1644 detect it. so don't bother checking for
1652 if ((*j)->feeds (*i)) {
1653 (*i)->fed_by.insert (*j);
1658 for (i = r->begin(); i != r->end(); ++i) {
1659 trace_terminal (*i, *i);
1666 cerr << "finished route resort\n";
1668 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1669 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1676 list<boost::shared_ptr<AudioTrack> >
1677 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1679 char track_name[32];
1680 uint32_t track_id = 0;
1682 uint32_t channels_used = 0;
1684 RouteList new_routes;
1685 list<boost::shared_ptr<AudioTrack> > ret;
1687 /* count existing audio tracks */
1690 shared_ptr<RouteList> r = routes.reader ();
1692 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1693 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1694 if (!(*i)->hidden()) {
1696 channels_used += (*i)->n_inputs();
1702 vector<string> physinputs;
1703 vector<string> physoutputs;
1704 uint32_t nphysical_in;
1705 uint32_t nphysical_out;
1707 _engine.get_physical_outputs (physoutputs);
1708 _engine.get_physical_inputs (physinputs);
1712 /* check for duplicate route names, since we might have pre-existing
1713 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1714 save, close,restart,add new route - first named route is now
1722 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1724 if (route_by_name (track_name) == 0) {
1728 } while (track_id < (UINT_MAX-1));
1730 if (input_auto_connect & AutoConnectPhysical) {
1731 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1736 if (output_auto_connect & AutoConnectPhysical) {
1737 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1743 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1745 if (track->ensure_io (input_channels, output_channels, false, this)) {
1746 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1747 input_channels, output_channels)
1752 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1756 if (input_auto_connect & AutoConnectPhysical) {
1757 port = physinputs[(channels_used+x)%nphysical_in];
1760 if (port.length() && track->connect_input (track->input (x), port, this)) {
1766 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1770 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1771 port = physoutputs[(channels_used+x)%nphysical_out];
1772 } else if (output_auto_connect & AutoConnectMaster) {
1774 port = _master_out->input (x%_master_out->n_inputs())->name();
1778 if (port.length() && track->connect_output (track->output (x), port, this)) {
1783 channels_used += track->n_inputs ();
1786 vector<string> cports;
1787 uint32_t ni = _control_out->n_inputs();
1789 for (n = 0; n < ni; ++n) {
1790 cports.push_back (_control_out->input(n)->name());
1793 track->set_control_outs (cports);
1796 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1797 track->set_remote_control_id (ntracks());
1799 new_routes.push_back (track);
1800 ret.push_back (track);
1803 catch (failed_constructor &err) {
1804 error << _("Session: could not create new audio track.") << endmsg;
1805 // XXX should we delete the tracks already created?
1813 if (!new_routes.empty()) {
1814 add_routes (new_routes, false);
1815 save_state (_current_snapshot_name);
1822 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1825 uint32_t bus_id = 1;
1830 /* count existing audio busses */
1833 shared_ptr<RouteList> r = routes.reader ();
1835 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1836 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1837 if (!(*i)->hidden()) {
1844 vector<string> physinputs;
1845 vector<string> physoutputs;
1847 _engine.get_physical_outputs (physoutputs);
1848 _engine.get_physical_inputs (physinputs);
1855 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1857 if (route_by_name (bus_name) == 0) {
1861 } while (bus_id < (UINT_MAX-1));
1864 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1866 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1867 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1868 input_channels, output_channels)
1872 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1876 if (input_auto_connect & AutoConnectPhysical) {
1877 port = physinputs[((n+x)%n_physical_inputs)];
1880 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1885 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1889 if (output_auto_connect & AutoConnectPhysical) {
1890 port = physoutputs[((n+x)%n_physical_outputs)];
1891 } else if (output_auto_connect & AutoConnectMaster) {
1893 port = _master_out->input (x%_master_out->n_inputs())->name();
1897 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1903 vector<string> cports;
1904 uint32_t ni = _control_out->n_inputs();
1906 for (uint32_t n = 0; n < ni; ++n) {
1907 cports.push_back (_control_out->input(n)->name());
1909 bus->set_control_outs (cports);
1912 ret.push_back (bus);
1916 catch (failed_constructor &err) {
1917 error << _("Session: could not create new audio route.") << endmsg;
1926 add_routes (ret, false);
1927 save_state (_current_snapshot_name);
1935 Session::add_routes (RouteList& new_routes, bool save)
1938 RCUWriter<RouteList> writer (routes);
1939 shared_ptr<RouteList> r = writer.get_copy ();
1940 r->insert (r->end(), new_routes.begin(), new_routes.end());
1941 resort_routes_using (r);
1944 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1945 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), (*x)));
1946 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1947 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1948 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1950 if ((*x)->master()) {
1954 if ((*x)->control()) {
1955 _control_out = (*x);
1962 save_state (_current_snapshot_name);
1965 RouteAdded (new_routes); /* EMIT SIGNAL */
1969 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1971 /* need to do this in case we're rolling at the time, to prevent false underruns */
1972 dstream->do_refill_with_alloc();
1975 RCUWriter<DiskstreamList> writer (diskstreams);
1976 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1977 ds->push_back (dstream);
1980 dstream->set_block_size (current_block_size);
1982 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1983 /* this will connect to future changes, and check the current length */
1984 diskstream_playlist_changed (dstream);
1986 dstream->prepare ();
1990 Session::remove_route (shared_ptr<Route> route)
1993 RCUWriter<RouteList> writer (routes);
1994 shared_ptr<RouteList> rs = writer.get_copy ();
1997 /* deleting the master out seems like a dumb
1998 idea, but its more of a UI policy issue
2002 if (route == _master_out) {
2003 _master_out = shared_ptr<Route> ((Route*) 0);
2006 if (route == _control_out) {
2007 _control_out = shared_ptr<Route> ((Route*) 0);
2009 /* cancel control outs for all routes */
2011 vector<string> empty;
2013 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2014 (*r)->set_control_outs (empty);
2018 update_route_solo_state ();
2020 /* writer goes out of scope, forces route list update */
2023 // FIXME: audio specific
2025 boost::shared_ptr<AudioDiskstream> ds;
2027 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2028 ds = at->audio_diskstream();
2034 RCUWriter<DiskstreamList> dsl (diskstreams);
2035 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2040 find_current_end ();
2042 update_latency_compensation (false, false);
2045 /* XXX should we disconnect from the Route's signals ? */
2047 save_state (_current_snapshot_name);
2049 /* try to cause everyone to drop their references */
2051 route->drop_references ();
2055 Session::route_mute_changed (void* src)
2061 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2063 if (solo_update_disabled) {
2070 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2072 shared_ptr<RouteList> r = routes.reader ();
2074 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2076 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2080 /* don't mess with busses */
2082 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2088 /* don't mess with tracks */
2090 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2095 if ((*i) != route &&
2096 ((*i)->mix_group () == 0 ||
2097 (*i)->mix_group () != route->mix_group () ||
2098 !route->mix_group ()->is_active())) {
2100 if ((*i)->soloed()) {
2102 /* if its already soloed, and solo latching is enabled,
2103 then leave it as it is.
2106 if (_solo_latched) {
2113 solo_update_disabled = true;
2114 (*i)->set_solo (false, src);
2115 solo_update_disabled = false;
2119 bool something_soloed = false;
2120 bool same_thing_soloed = false;
2121 bool signal = false;
2123 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2124 if ((*i)->soloed()) {
2125 something_soloed = true;
2126 if (dynamic_cast<AudioTrack*>((*i).get())) {
2128 same_thing_soloed = true;
2133 same_thing_soloed = true;
2141 if (something_soloed != currently_soloing) {
2143 currently_soloing = something_soloed;
2146 modify_solo_mute (is_track, same_thing_soloed);
2149 SoloActive (currently_soloing);
2156 Session::set_solo_latched (bool yn)
2158 if (yn != _solo_latched) {
2161 ControlChanged (SoloLatch);
2166 Session::update_route_solo_state ()
2169 bool is_track = false;
2170 bool signal = false;
2172 /* caller must hold RouteLock */
2174 /* this is where we actually implement solo by changing
2175 the solo mute setting of each track.
2178 shared_ptr<RouteList> r = routes.reader ();
2180 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2181 if ((*i)->soloed()) {
2183 if (dynamic_cast<AudioTrack*>((*i).get())) {
2190 if (mute != currently_soloing) {
2192 currently_soloing = mute;
2195 if (!is_track && !mute) {
2197 /* nothing is soloed */
2199 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2200 (*i)->set_solo_mute (false);
2210 modify_solo_mute (is_track, mute);
2213 SoloActive (currently_soloing);
2218 Session::modify_solo_mute (bool is_track, bool mute)
2220 shared_ptr<RouteList> r = routes.reader ();
2222 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2226 /* only alter track solo mute */
2228 if (dynamic_cast<AudioTrack*>((*i).get())) {
2229 if ((*i)->soloed()) {
2230 (*i)->set_solo_mute (!mute);
2232 (*i)->set_solo_mute (mute);
2238 /* only alter bus solo mute */
2240 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2242 if ((*i)->soloed()) {
2244 (*i)->set_solo_mute (false);
2248 /* don't mute master or control outs
2249 in response to another bus solo
2252 if ((*i) != _master_out &&
2253 (*i) != _control_out) {
2254 (*i)->set_solo_mute (mute);
2265 Session::catch_up_on_solo ()
2267 /* this is called after set_state() to catch the full solo
2268 state, which can't be correctly determined on a per-route
2269 basis, but needs the global overview that only the session
2272 update_route_solo_state();
2276 Session::route_by_name (string name)
2278 shared_ptr<RouteList> r = routes.reader ();
2280 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2281 if ((*i)->name() == name) {
2286 return shared_ptr<Route> ((Route*) 0);
2290 Session::route_by_id (PBD::ID id)
2292 shared_ptr<RouteList> r = routes.reader ();
2294 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2295 if ((*i)->id() == id) {
2300 return shared_ptr<Route> ((Route*) 0);
2304 Session::route_by_remote_id (uint32_t id)
2306 shared_ptr<RouteList> r = routes.reader ();
2308 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2309 if ((*i)->remote_control_id() == id) {
2314 return shared_ptr<Route> ((Route*) 0);
2318 Session::find_current_end ()
2320 if (_state_of_the_state & Loading) {
2324 jack_nframes_t max = get_maximum_extent ();
2326 if (max > end_location->end()) {
2327 end_location->set_end (max);
2329 DurationChanged(); /* EMIT SIGNAL */
2334 Session::get_maximum_extent () const
2336 jack_nframes_t max = 0;
2339 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2341 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2342 Playlist* pl = (*i)->playlist();
2343 if ((me = pl->get_maximum_extent()) > max) {
2351 boost::shared_ptr<Diskstream>
2352 Session::diskstream_by_name (string name)
2354 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2356 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2357 if ((*i)->name() == name) {
2362 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2365 boost::shared_ptr<Diskstream>
2366 Session::diskstream_by_id (const PBD::ID& id)
2368 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2370 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2371 if ((*i)->id() == id) {
2376 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2379 /* AudioRegion management */
2382 Session::new_region_name (string old)
2384 string::size_type last_period;
2386 string::size_type len = old.length() + 64;
2389 if ((last_period = old.find_last_of ('.')) == string::npos) {
2391 /* no period present - add one explicitly */
2394 last_period = old.length() - 1;
2399 number = atoi (old.substr (last_period+1).c_str());
2403 while (number < (UINT_MAX-1)) {
2405 AudioRegionList::const_iterator i;
2410 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2413 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2414 if (i->second->name() == sbuf) {
2419 if (i == audio_regions.end()) {
2424 if (number != (UINT_MAX-1)) {
2428 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2433 Session::region_name (string& result, string base, bool newlevel) const
2440 Glib::Mutex::Lock lm (region_lock);
2442 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2450 /* XXX this is going to be slow. optimize me later */
2455 string::size_type pos;
2457 pos = base.find_last_of ('.');
2459 /* pos may be npos, but then we just use entire base */
2461 subbase = base.substr (0, pos);
2465 bool name_taken = true;
2468 Glib::Mutex::Lock lm (region_lock);
2470 for (int n = 1; n < 5000; ++n) {
2473 snprintf (buf, sizeof (buf), ".%d", n);
2478 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2479 if (i->second->name() == result) {
2492 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2500 Session::add_region (boost::shared_ptr<Region> region)
2502 boost::shared_ptr<AudioRegion> ar;
2503 boost::shared_ptr<AudioRegion> oar;
2507 Glib::Mutex::Lock lm (region_lock);
2509 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2511 AudioRegionList::iterator x;
2513 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2515 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2517 if (ar->region_list_equivalent (oar)) {
2522 if (x == audio_regions.end()) {
2524 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2526 entry.first = region->id();
2529 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2541 fatal << _("programming error: ")
2542 << X_("unknown region type passed to Session::add_region()")
2549 /* mark dirty because something has changed even if we didn't
2550 add the region to the region list.
2556 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
2557 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2558 AudioRegionAdded (ar); /* EMIT SIGNAL */
2563 Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
2565 if (what_changed & Region::HiddenChanged) {
2566 /* relay hidden changes */
2567 RegionHiddenChange (region);
2572 Session::region_renamed (boost::shared_ptr<Region> region)
2574 add_region (region);
2578 Session::remove_region (boost::shared_ptr<Region> region)
2580 AudioRegionList::iterator i;
2581 boost::shared_ptr<AudioRegion> ar;
2582 bool removed = false;
2585 Glib::Mutex::Lock lm (region_lock);
2587 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2588 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2589 audio_regions.erase (i);
2595 fatal << _("programming error: ")
2596 << X_("unknown region type passed to Session::remove_region()")
2602 /* mark dirty because something has changed even if we didn't
2603 remove the region from the region list.
2609 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2613 boost::shared_ptr<AudioRegion>
2614 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2616 AudioRegionList::iterator i;
2617 boost::shared_ptr<AudioRegion> region;
2618 Glib::Mutex::Lock lm (region_lock);
2620 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2624 if (region->whole_file()) {
2626 if (child->source_equivalent (region)) {
2632 return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
2636 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2638 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2639 (*i)->get_region_list_equivalent_regions (region, result);
2643 Session::destroy_region (boost::shared_ptr<Region> region)
2645 boost::shared_ptr<AudioRegion> aregion;
2647 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2651 if (aregion->playlist()) {
2652 aregion->playlist()->destroy_region (region);
2655 vector<boost::shared_ptr<Source> > srcs;
2657 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2658 srcs.push_back (aregion->source (n));
2661 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2663 if ((*i).use_count() == 1) {
2664 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2667 (afs)->mark_for_remove ();
2670 (*i)->drop_references ();
2678 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2680 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2681 destroy_region (*i);
2687 Session::remove_last_capture ()
2689 list<boost::shared_ptr<Region> > r;
2691 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2693 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2694 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2697 r.insert (r.end(), l.begin(), l.end());
2702 destroy_regions (r);
2707 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2713 /* Source Management */
2716 Session::add_source (boost::shared_ptr<Source> source)
2718 boost::shared_ptr<AudioFileSource> afs;
2720 cerr << "add new source " << source->name() << endl;
2722 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2724 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2725 pair<AudioSourceList::iterator,bool> result;
2727 entry.first = source->id();
2731 Glib::Mutex::Lock lm (audio_source_lock);
2732 result = audio_sources.insert (entry);
2735 if (!result.second) {
2736 cerr << "\tNOT inserted ? " << result.second << endl;
2739 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2742 SourceAdded (source); /* EMIT SIGNAL */
2744 cerr << "\tNOT AUDIO FILE\n";
2749 Session::remove_source (boost::weak_ptr<Source> src)
2751 AudioSourceList::iterator i;
2752 boost::shared_ptr<Source> source = src.lock();
2755 cerr << "removing a source DEAD\n";
2757 cerr << "removing a source " << source->name () << endl;
2760 Glib::Mutex::Lock lm (audio_source_lock);
2762 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2763 audio_sources.erase (i);
2767 if (!_state_of_the_state & InCleanup) {
2769 /* save state so we don't end up with a session file
2770 referring to non-existent sources.
2773 save_state (_current_snapshot_name);
2776 SourceRemoved(source); /* EMIT SIGNAL */
2780 boost::shared_ptr<Source>
2781 Session::source_by_id (const PBD::ID& id)
2783 Glib::Mutex::Lock lm (audio_source_lock);
2784 AudioSourceList::iterator i;
2785 boost::shared_ptr<Source> source;
2787 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2791 /* XXX search MIDI or other searches here */
2797 Session::peak_path_from_audio_path (string audio_path)
2799 /* XXX hardly bombproof! fix me */
2803 res = Glib::path_get_dirname (audio_path);
2804 res = Glib::path_get_dirname (res);
2806 res += peak_dir_name;
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) {
2954 spath += tape_dir_name;
2956 spath += sound_dir_name;
2961 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2962 } else if (nchan == 2) {
2964 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2966 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2968 } else if (nchan < 26) {
2969 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2971 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2979 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2980 } else if (nchan == 2) {
2982 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2984 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2986 } else if (nchan < 26) {
2987 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2989 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2993 if (access (buf, F_OK) == 0) {
2998 if (existing == 0) {
3003 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3004 throw failed_constructor();
3008 /* we now have a unique name for the file, but figure out where to
3015 spath = tape_dir ();
3017 spath = discover_best_sound_dir ();
3020 string::size_type pos = foo.find_last_of ('/');
3022 if (pos == string::npos) {
3025 spath += foo.substr (pos + 1);
3031 boost::shared_ptr<AudioFileSource>
3032 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3034 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3035 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (spath, destructive, frame_rate()));
3038 /* Playlist management */
3041 Session::playlist_by_name (string name)
3043 Glib::Mutex::Lock lm (playlist_lock);
3044 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3045 if ((*i)->name() == name) {
3049 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3050 if ((*i)->name() == name) {
3058 Session::add_playlist (Playlist* playlist)
3060 if (playlist->hidden()) {
3065 Glib::Mutex::Lock lm (playlist_lock);
3066 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3067 playlists.insert (playlists.begin(), playlist);
3069 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3070 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
3076 PlaylistAdded (playlist); /* EMIT SIGNAL */
3080 Session::track_playlist (Playlist* pl, bool inuse)
3082 PlaylistList::iterator x;
3085 Glib::Mutex::Lock lm (playlist_lock);
3088 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3090 unused_playlists.insert (pl);
3092 if ((x = playlists.find (pl)) != playlists.end()) {
3093 playlists.erase (x);
3098 //cerr << "shifting playlist to used: " << pl->name() << endl;
3100 playlists.insert (pl);
3102 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3103 unused_playlists.erase (x);
3110 Session::remove_playlist (Playlist* playlist)
3112 if (_state_of_the_state & Deletion) {
3117 Glib::Mutex::Lock lm (playlist_lock);
3118 // cerr << "removing playlist: " << playlist->name() << endl;
3120 PlaylistList::iterator i;
3122 i = find (playlists.begin(), playlists.end(), playlist);
3124 if (i != playlists.end()) {
3125 playlists.erase (i);
3128 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3129 if (i != unused_playlists.end()) {
3130 unused_playlists.erase (i);
3137 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3141 Session::set_audition (boost::shared_ptr<Region> r)
3143 pending_audition_region = r;
3144 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3145 schedule_butler_transport_work ();
3149 Session::audition_playlist ()
3151 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3152 ev->region.reset ();
3157 Session::non_realtime_set_audition ()
3159 if (!pending_audition_region) {
3160 auditioner->audition_current_playlist ();
3162 auditioner->audition_region (pending_audition_region);
3163 pending_audition_region.reset ();
3165 AuditionActive (true); /* EMIT SIGNAL */
3169 Session::audition_region (boost::shared_ptr<Region> r)
3171 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3177 Session::cancel_audition ()
3179 if (auditioner->active()) {
3180 auditioner->cancel_audition ();
3181 AuditionActive (false); /* EMIT SIGNAL */
3186 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3188 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3192 Session::remove_empty_sounds ()
3195 PathScanner scanner;
3200 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3202 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3204 if (AudioFileSource::is_empty (*(*i))) {
3206 unlink ((*i)->c_str());
3208 string peak_path = peak_path_from_audio_path (**i);
3209 unlink (peak_path.c_str());
3215 delete possible_audiofiles;
3219 Session::is_auditioning () const
3221 /* can be called before we have an auditioner object */
3223 return auditioner->active();
3230 Session::set_all_solo (bool yn)
3232 shared_ptr<RouteList> r = routes.reader ();
3234 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3235 if (!(*i)->hidden()) {
3236 (*i)->set_solo (yn, this);
3244 Session::set_all_mute (bool yn)
3246 shared_ptr<RouteList> r = routes.reader ();
3248 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3249 if (!(*i)->hidden()) {
3250 (*i)->set_mute (yn, this);
3258 Session::n_diskstreams () const
3262 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3264 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3265 if (!(*i)->hidden()) {
3273 Session::graph_reordered ()
3275 /* don't do this stuff if we are setting up connections
3276 from a set_state() call.
3279 if (_state_of_the_state & InitialConnecting) {
3285 /* force all diskstreams to update their capture offset values to
3286 reflect any changes in latencies within the graph.
3289 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3291 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3292 (*i)->set_capture_offset ();
3297 Session::record_disenable_all ()
3299 record_enable_change_all (false);
3303 Session::record_enable_all ()
3305 record_enable_change_all (true);
3309 Session::record_enable_change_all (bool yn)
3311 shared_ptr<RouteList> r = routes.reader ();
3313 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3316 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3317 at->set_record_enable (yn, this);
3321 /* since we don't keep rec-enable state, don't mark session dirty */
3325 Session::add_redirect (Redirect* redirect)
3329 PortInsert* port_insert;
3330 PluginInsert* plugin_insert;
3332 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3333 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3334 _port_inserts.insert (_port_inserts.begin(), port_insert);
3335 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3336 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3338 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3341 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3342 _sends.insert (_sends.begin(), send);
3344 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3348 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3354 Session::remove_redirect (Redirect* redirect)
3358 PortInsert* port_insert;
3359 PluginInsert* plugin_insert;
3361 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3362 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3363 _port_inserts.remove (port_insert);
3364 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3365 _plugin_inserts.remove (plugin_insert);
3367 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3370 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3371 _sends.remove (send);
3373 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3381 Session::available_capture_duration ()
3383 const double scale = 4096.0 / sizeof (Sample);
3385 if (_total_free_4k_blocks * scale > (double) max_frames) {
3389 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3393 Session::add_connection (ARDOUR::Connection* connection)
3396 Glib::Mutex::Lock guard (connection_lock);
3397 _connections.push_back (connection);
3400 ConnectionAdded (connection); /* EMIT SIGNAL */
3406 Session::remove_connection (ARDOUR::Connection* connection)
3408 bool removed = false;
3411 Glib::Mutex::Lock guard (connection_lock);
3412 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3414 if (i != _connections.end()) {
3415 _connections.erase (i);
3421 ConnectionRemoved (connection); /* EMIT SIGNAL */
3427 ARDOUR::Connection *
3428 Session::connection_by_name (string name) const
3430 Glib::Mutex::Lock lm (connection_lock);
3432 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3433 if ((*i)->name() == name) {
3442 Session::set_edit_mode (EditMode mode)
3447 Glib::Mutex::Lock lm (playlist_lock);
3449 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3450 (*i)->set_edit_mode (mode);
3455 ControlChanged (EditingMode); /* EMIT SIGNAL */
3459 Session::tempo_map_changed (Change ignored)
3466 Session::ensure_passthru_buffers (uint32_t howmany)
3468 while (howmany > _passthru_buffers.size()) {
3470 #ifdef NO_POSIX_MEMALIGN
3471 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3473 posix_memalign((void **)&p,16,current_block_size * 4);
3475 _passthru_buffers.push_back (p);
3479 #ifdef NO_POSIX_MEMALIGN
3480 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3482 posix_memalign((void **)&p,16,current_block_size * 4);
3484 memset (p, 0, sizeof (Sample) * current_block_size);
3485 _silent_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 _send_buffers.push_back (p);
3498 allocate_pan_automation_buffers (current_block_size, howmany, false);
3502 Session::next_send_name ()
3505 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3510 Session::next_insert_name ()
3513 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3517 /* Named Selection management */
3520 Session::named_selection_by_name (string name)
3522 Glib::Mutex::Lock lm (named_selection_lock);
3523 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3524 if ((*i)->name == name) {
3532 Session::add_named_selection (NamedSelection* named_selection)
3535 Glib::Mutex::Lock lm (named_selection_lock);
3536 named_selections.insert (named_selections.begin(), named_selection);
3541 NamedSelectionAdded (); /* EMIT SIGNAL */
3545 Session::remove_named_selection (NamedSelection* named_selection)
3547 bool removed = false;
3550 Glib::Mutex::Lock lm (named_selection_lock);
3552 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3554 if (i != named_selections.end()) {
3556 named_selections.erase (i);
3563 NamedSelectionRemoved (); /* EMIT SIGNAL */
3568 Session::reset_native_file_format ()
3570 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3572 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3573 (*i)->reset_write_sources (false);
3578 Session::route_name_unique (string n) const
3580 shared_ptr<RouteList> r = routes.reader ();
3582 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3583 if ((*i)->name() == n) {
3592 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3594 return fs->move_to_trash (dead_sound_dir_name);
3598 Session::n_playlists () const
3600 Glib::Mutex::Lock lm (playlist_lock);
3601 return playlists.size();
3605 Session::set_solo_model (SoloModel sm)
3607 if (sm != _solo_model) {
3609 ControlChanged (SoloingModel);
3615 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3617 if (!force && howmany <= _npan_buffers) {
3621 if (_pan_automation_buffer) {
3623 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3624 delete [] _pan_automation_buffer[i];
3627 delete [] _pan_automation_buffer;
3630 _pan_automation_buffer = new pan_t*[howmany];
3632 for (uint32_t i = 0; i < howmany; ++i) {
3633 _pan_automation_buffer[i] = new pan_t[nframes];
3636 _npan_buffers = howmany;
3640 Session::freeze (InterThreadInfo& itt)
3642 shared_ptr<RouteList> r = routes.reader ();
3644 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3648 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3649 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3660 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3661 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3665 boost::shared_ptr<AudioFileSource> fsource;
3667 char buf[PATH_MAX+1];
3670 jack_nframes_t position;
3671 jack_nframes_t this_chunk;
3672 jack_nframes_t to_do;
3673 vector<Sample*> buffers;
3675 // any bigger than this seems to cause stack overflows in called functions
3676 const jack_nframes_t chunk_size = (128 * 1024)/4;
3678 g_atomic_int_set (&processing_prohibited, 1);
3680 /* call tree *MUST* hold route_lock */
3682 if ((playlist = track.diskstream()->playlist()) == 0) {
3686 /* external redirects will be a problem */
3688 if (track.has_external_redirects()) {
3692 nchans = track.audio_diskstream()->n_channels();
3694 dir = discover_best_sound_dir ();
3696 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3698 for (x = 0; x < 99999; ++x) {
3699 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3700 if (access (buf, F_OK) != 0) {
3706 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3711 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (buf, false, frame_rate()));
3714 catch (failed_constructor& err) {
3715 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3719 srcs.push_back (fsource);
3722 /* XXX need to flush all redirects */
3727 /* create a set of reasonably-sized buffers */
3729 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3731 #ifdef NO_POSIX_MEMALIGN
3732 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3734 posix_memalign((void **)&b,16,chunk_size * 4);
3736 buffers.push_back (b);
3739 while (to_do && !itt.cancel) {
3741 this_chunk = min (to_do, chunk_size);
3743 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3748 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3749 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3752 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3758 start += this_chunk;
3759 to_do -= this_chunk;
3761 itt.progress = (float) (1.0 - ((double) to_do / len));
3770 xnow = localtime (&now);
3772 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3773 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3776 afs->update_header (position, *xnow, now);
3780 /* build peakfile for new source */
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);
3785 afs->build_peaks ();
3794 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3795 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3798 afs->mark_for_remove ();
3801 (*src)->drop_references ();
3805 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3809 g_atomic_int_set (&processing_prohibited, 0);
3817 Session::get_silent_buffers (uint32_t howmany)
3819 for (uint32_t i = 0; i < howmany; ++i) {
3820 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3822 return _silent_buffers;
3826 Session::ntracks () const
3829 shared_ptr<RouteList> r = routes.reader ();
3831 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3832 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3841 Session::nbusses () const
3844 shared_ptr<RouteList> r = routes.reader ();
3846 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3847 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3856 Session::set_layer_model (LayerModel lm)
3858 if (lm != layer_model) {
3861 ControlChanged (LayeringModel);
3866 Session::set_xfade_model (CrossfadeModel xm)
3868 if (xm != xfade_model) {
3871 ControlChanged (CrossfadingModel);
3876 Session::add_curve(Curve *curve)
3878 curves[curve->id()] = curve;
3882 Session::add_automation_list(AutomationList *al)
3884 automation_lists[al->id()] = al;