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>
69 #include <ardour/region_factory.h>
72 #include <ardour/osc.h>
78 using namespace ARDOUR;
80 using boost::shared_ptr;
82 const char* Session::_template_suffix = X_(".template");
83 const char* Session::_statefile_suffix = X_(".ardour");
84 const char* Session::_pending_suffix = X_(".pending");
85 const char* Session::old_sound_dir_name = X_("sounds");
86 const char* Session::sound_dir_name = X_("audiofiles");
87 const char* Session::peak_dir_name = X_("peaks");
88 const char* Session::dead_sound_dir_name = X_("dead_sounds");
89 const char* Session::interchange_dir_name = X_("interchange");
91 Session::compute_peak_t Session::compute_peak = 0;
92 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
93 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
94 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
96 sigc::signal<int> Session::AskAboutPendingState;
97 sigc::signal<void> Session::SendFeedback;
99 sigc::signal<void> Session::SMPTEOffsetChanged;
100 sigc::signal<void> Session::StartTimeChanged;
101 sigc::signal<void> Session::EndTimeChanged;
104 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
107 char buf[PATH_MAX+1];
111 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
112 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
118 /* check to see if it exists, and what it is */
120 if (stat (str.c_str(), &statbuf)) {
121 if (errno == ENOENT) {
124 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
132 /* it exists, so it must either be the name
133 of the directory, or the name of the statefile
137 if (S_ISDIR (statbuf.st_mode)) {
139 string::size_type slash = str.find_last_of ('/');
141 if (slash == string::npos) {
143 /* a subdirectory of cwd, so statefile should be ... */
149 tmp += _statefile_suffix;
153 if (stat (tmp.c_str(), &statbuf)) {
154 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
164 /* some directory someplace in the filesystem.
165 the snapshot name is the directory name
170 snapshot = str.substr (slash+1);
174 } else if (S_ISREG (statbuf.st_mode)) {
176 string::size_type slash = str.find_last_of ('/');
177 string::size_type suffix;
179 /* remove the suffix */
181 if (slash != string::npos) {
182 snapshot = str.substr (slash+1);
187 suffix = snapshot.find (_statefile_suffix);
189 if (suffix == string::npos) {
190 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
196 snapshot = snapshot.substr (0, suffix);
198 if (slash == string::npos) {
200 /* we must be in the directory where the
201 statefile lives. get it using cwd().
204 char cwd[PATH_MAX+1];
206 if (getcwd (cwd, sizeof (cwd)) == 0) {
207 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
216 /* full path to the statefile */
218 path = str.substr (0, slash);
223 /* what type of file is it? */
224 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
230 /* its the name of a new directory. get the name
234 string::size_type slash = str.find_last_of ('/');
236 if (slash == string::npos) {
238 /* no slash, just use the name, but clean it up */
240 path = legalize_for_path (str);
246 snapshot = str.substr (slash+1);
253 Session::Session (AudioEngine &eng,
255 string snapshot_name,
256 string* mix_template)
259 _mmc_port (default_mmc_port),
260 _mtc_port (default_mtc_port),
261 _midi_port (default_midi_port),
262 pending_events (2048),
263 midi_requests (128), // the size of this should match the midi request pool size
264 diskstreams (new DiskstreamList),
265 routes (new RouteList),
266 auditioner ((Auditioner*) 0),
272 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
274 n_physical_outputs = _engine.n_physical_outputs();
275 n_physical_inputs = _engine.n_physical_inputs();
277 first_stage_init (fullpath, snapshot_name);
279 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
281 if (create (new_session, mix_template, compute_initial_length())) {
282 cerr << "create failed\n";
283 throw failed_constructor ();
287 if (second_stage_init (new_session)) {
288 cerr << "2nd state failed\n";
289 throw failed_constructor ();
292 store_recent_sessions(_name, _path);
294 bool was_dirty = dirty();
296 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
298 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
301 DirtyChanged (); /* EMIT SIGNAL */
305 Session::Session (AudioEngine &eng,
307 string snapshot_name,
308 AutoConnectOption input_ac,
309 AutoConnectOption output_ac,
310 uint32_t control_out_channels,
311 uint32_t master_out_channels,
312 uint32_t requested_physical_in,
313 uint32_t requested_physical_out,
314 nframes_t initial_length)
317 _mmc_port (default_mmc_port),
318 _mtc_port (default_mtc_port),
319 _midi_port (default_midi_port),
320 pending_events (2048),
322 diskstreams (new DiskstreamList),
323 routes (new RouteList),
329 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
331 n_physical_outputs = _engine.n_physical_outputs();
332 n_physical_inputs = _engine.n_physical_inputs();
334 if (n_physical_inputs) {
335 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
338 if (n_physical_outputs) {
339 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
342 first_stage_init (fullpath, snapshot_name);
344 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
347 if (create (new_session, 0, initial_length)) {
348 throw failed_constructor ();
352 if (control_out_channels) {
353 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
360 if (master_out_channels) {
361 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
367 /* prohibit auto-connect to master, because there isn't one */
368 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
371 Config->set_input_auto_connect (input_ac);
372 Config->set_output_auto_connect (output_ac);
374 if (second_stage_init (new_session)) {
375 throw failed_constructor ();
378 store_recent_sessions(_name, _path);
380 bool was_dirty = dirty ();
382 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
385 DirtyChanged (); /* EMIT SIGNAL */
391 /* if we got to here, leaving pending capture state around
395 remove_pending_capture_state ();
397 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
398 _engine.remove_session ();
400 GoingAway (); /* EMIT SIGNAL */
406 /* clear history so that no references to objects are held any more */
410 /* clear state tree so that no references to objects are held any more */
416 terminate_butler_thread ();
417 terminate_midi_thread ();
419 if (click_data && click_data != default_click) {
420 delete [] click_data;
423 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
424 delete [] click_emphasis_data;
429 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
433 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
437 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
441 AudioDiskstream::free_working_buffers();
443 /* this should cause deletion of the auditioner */
445 // auditioner.reset ();
447 #undef TRACK_DESTRUCTION
448 #ifdef TRACK_DESTRUCTION
449 cerr << "delete named selections\n";
450 #endif /* TRACK_DESTRUCTION */
451 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
452 NamedSelectionList::iterator tmp;
461 #ifdef TRACK_DESTRUCTION
462 cerr << "delete playlists\n";
463 #endif /* TRACK_DESTRUCTION */
464 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
465 PlaylistList::iterator tmp;
475 #ifdef TRACK_DESTRUCTION
476 cerr << "delete audio regions\n";
477 #endif /* TRACK_DESTRUCTION */
479 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
480 AudioRegionList::iterator tmp;
485 i->second->drop_references ();
490 audio_regions.clear ();
492 #ifdef TRACK_DESTRUCTION
493 cerr << "delete routes\n";
494 #endif /* TRACK_DESTRUCTION */
496 RCUWriter<RouteList> writer (routes);
497 boost::shared_ptr<RouteList> r = writer.get_copy ();
498 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
499 (*i)->drop_references ();
502 /* writer goes out of scope and updates master */
507 #ifdef TRACK_DESTRUCTION
508 cerr << "delete diskstreams\n";
509 #endif /* TRACK_DESTRUCTION */
511 RCUWriter<DiskstreamList> dwriter (diskstreams);
512 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
513 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
514 (*i)->drop_references ();
518 diskstreams.flush ();
520 #ifdef TRACK_DESTRUCTION
521 cerr << "delete audio sources\n";
522 #endif /* TRACK_DESTRUCTION */
523 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
524 AudioSourceList::iterator tmp;
529 i->second->drop_references ();
534 audio_sources.clear ();
536 #ifdef TRACK_DESTRUCTION
537 cerr << "delete mix groups\n";
538 #endif /* TRACK_DESTRUCTION */
539 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
540 list<RouteGroup*>::iterator tmp;
550 #ifdef TRACK_DESTRUCTION
551 cerr << "delete edit groups\n";
552 #endif /* TRACK_DESTRUCTION */
553 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
554 list<RouteGroup*>::iterator tmp;
564 #ifdef TRACK_DESTRUCTION
565 cerr << "delete connections\n";
566 #endif /* TRACK_DESTRUCTION */
567 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
568 ConnectionList::iterator tmp;
578 if (butler_mixdown_buffer) {
579 delete [] butler_mixdown_buffer;
582 if (butler_gain_buffer) {
583 delete [] butler_gain_buffer;
586 Crossfade::set_buffer_size (0);
594 Session::set_worst_io_latencies ()
596 _worst_output_latency = 0;
597 _worst_input_latency = 0;
599 if (!_engine.connected()) {
603 boost::shared_ptr<RouteList> r = routes.reader ();
605 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
606 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
607 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
612 Session::when_engine_running ()
614 string first_physical_output;
616 /* we don't want to run execute this again */
618 first_time_running.disconnect ();
620 set_block_size (_engine.frames_per_cycle());
621 set_frame_rate (_engine.frame_rate());
623 Config->map_parameters (mem_fun (*this, &Session::config_changed));
625 /* every time we reconnect, recompute worst case output latencies */
627 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
629 if (synced_to_jack()) {
630 _engine.transport_stop ();
633 if (Config->get_jack_time_master()) {
634 _engine.transport_locate (_transport_frame);
642 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
644 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
646 /* existing state for Click */
648 if (_click_io->set_state (*child->children().front()) == 0) {
650 _clicking = Config->get_clicking ();
654 error << _("could not setup Click I/O") << endmsg;
660 /* default state for Click */
662 first_physical_output = _engine.get_nth_physical_output (0);
664 if (first_physical_output.length()) {
665 if (_click_io->add_output_port (first_physical_output, this)) {
666 // relax, even though its an error
668 _clicking = Config->get_clicking ();
674 catch (failed_constructor& err) {
675 error << _("cannot setup Click I/O") << endmsg;
678 set_worst_io_latencies ();
681 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
684 if (auditioner == 0) {
686 /* we delay creating the auditioner till now because
687 it makes its own connections to ports named
688 in the ARDOUR_RC config file. the engine has
689 to be running for this to work.
693 auditioner.reset (new Auditioner (*this));
696 catch (failed_constructor& err) {
697 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
701 /* Create a set of Connection objects that map
702 to the physical outputs currently available
707 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
709 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
711 Connection* c = new OutputConnection (buf, true);
714 c->add_connection (0, _engine.get_nth_physical_output (np));
719 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
721 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
723 Connection* c = new InputConnection (buf, true);
726 c->add_connection (0, _engine.get_nth_physical_input (np));
733 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
735 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
737 Connection* c = new OutputConnection (buf, true);
741 c->add_connection (0, _engine.get_nth_physical_output (np));
742 c->add_connection (1, _engine.get_nth_physical_output (np+1));
747 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
749 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
751 Connection* c = new InputConnection (buf, true);
755 c->add_connection (0, _engine.get_nth_physical_input (np));
756 c->add_connection (1, _engine.get_nth_physical_input (np+1));
765 /* create master/control ports */
770 /* force the master to ignore any later call to this */
772 if (_master_out->pending_state_node) {
773 _master_out->ports_became_legal();
776 /* no panner resets till we are through */
778 _master_out->defer_pan_reset ();
780 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
781 if (_master_out->add_input_port ("", this)) {
782 error << _("cannot setup master inputs")
788 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
789 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
790 error << _("cannot setup master outputs")
797 _master_out->allow_pan_reset ();
801 Connection* c = new OutputConnection (_("Master Out"), true);
803 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
805 c->add_connection ((int) n, _master_out->input(n)->name());
812 /* catch up on send+insert cnts */
816 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
819 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
820 if (id > insert_cnt) {
828 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
831 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
838 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
840 /* hook us up to the engine */
842 _engine.set_session (this);
847 osc->set_session (*this);
850 _state_of_the_state = Clean;
852 DirtyChanged (); /* EMIT SIGNAL */
856 Session::hookup_io ()
858 /* stop graph reordering notifications from
859 causing resorts, etc.
862 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
864 /* Tell all IO objects to create their ports */
871 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
872 if (_control_out->add_input_port ("", this)) {
873 error << _("cannot setup control inputs")
879 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
880 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
881 error << _("cannot set up master outputs")
889 /* Tell all IO objects to connect themselves together */
891 IO::enable_connecting ();
893 /* Now reset all panners */
895 IO::reset_panners ();
897 /* Anyone who cares about input state, wake up and do something */
899 IOConnectionsComplete (); /* EMIT SIGNAL */
901 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
903 /* now handle the whole enchilada as if it was one
909 /* update mixer solo state */
915 Session::playlist_length_changed (Playlist* pl)
917 /* we can't just increase end_location->end() if pl->get_maximum_extent()
918 if larger. if the playlist used to be the longest playlist,
919 and its now shorter, we have to decrease end_location->end(). hence,
920 we have to iterate over all diskstreams and check the
921 playlists currently in use.
927 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
931 if ((playlist = dstream->playlist()) != 0) {
932 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
935 /* see comment in playlist_length_changed () */
940 Session::record_enabling_legal () const
942 /* this used to be in here, but survey says.... we don't need to restrict it */
943 // if (record_status() == Recording) {
947 if (Config->get_all_safe()) {
954 Session::reset_input_monitor_state ()
956 if (transport_rolling()) {
958 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
960 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
961 if ((*i)->record_enabled ()) {
962 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
963 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
967 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
969 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
970 if ((*i)->record_enabled ()) {
971 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
972 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
979 Session::auto_punch_start_changed (Location* location)
981 replace_event (Event::PunchIn, location->start());
983 if (get_record_enabled() && Config->get_punch_in()) {
984 /* capture start has been changed, so save new pending state */
985 save_state ("", true);
990 Session::auto_punch_end_changed (Location* location)
992 nframes_t when_to_stop = location->end();
993 // when_to_stop += _worst_output_latency + _worst_input_latency;
994 replace_event (Event::PunchOut, when_to_stop);
998 Session::auto_punch_changed (Location* location)
1000 nframes_t when_to_stop = location->end();
1002 replace_event (Event::PunchIn, location->start());
1003 //when_to_stop += _worst_output_latency + _worst_input_latency;
1004 replace_event (Event::PunchOut, when_to_stop);
1008 Session::auto_loop_changed (Location* location)
1010 replace_event (Event::AutoLoop, location->end(), location->start());
1012 if (transport_rolling() && play_loop) {
1014 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1016 if (_transport_frame > location->end()) {
1017 // relocate to beginning of loop
1018 clear_events (Event::LocateRoll);
1020 request_locate (location->start(), true);
1023 else if (Config->get_seamless_loop() && !loop_changing) {
1025 // schedule a locate-roll to refill the diskstreams at the
1026 // previous loop end
1027 loop_changing = true;
1029 if (location->end() > last_loopend) {
1030 clear_events (Event::LocateRoll);
1031 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1038 last_loopend = location->end();
1043 Session::set_auto_punch_location (Location* location)
1047 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1048 auto_punch_start_changed_connection.disconnect();
1049 auto_punch_end_changed_connection.disconnect();
1050 auto_punch_changed_connection.disconnect();
1051 existing->set_auto_punch (false, this);
1052 remove_event (existing->start(), Event::PunchIn);
1053 clear_events (Event::PunchOut);
1054 auto_punch_location_changed (0);
1059 if (location == 0) {
1063 if (location->end() <= location->start()) {
1064 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1068 auto_punch_start_changed_connection.disconnect();
1069 auto_punch_end_changed_connection.disconnect();
1070 auto_punch_changed_connection.disconnect();
1072 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1073 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1074 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1076 location->set_auto_punch (true, this);
1077 auto_punch_location_changed (location);
1081 Session::set_auto_loop_location (Location* location)
1085 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1086 auto_loop_start_changed_connection.disconnect();
1087 auto_loop_end_changed_connection.disconnect();
1088 auto_loop_changed_connection.disconnect();
1089 existing->set_auto_loop (false, this);
1090 remove_event (existing->end(), Event::AutoLoop);
1091 auto_loop_location_changed (0);
1096 if (location == 0) {
1100 if (location->end() <= location->start()) {
1101 error << _("Session: you can't use a mark for auto loop") << endmsg;
1105 last_loopend = location->end();
1107 auto_loop_start_changed_connection.disconnect();
1108 auto_loop_end_changed_connection.disconnect();
1109 auto_loop_changed_connection.disconnect();
1111 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1112 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1113 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1115 location->set_auto_loop (true, this);
1116 auto_loop_location_changed (location);
1120 Session::locations_added (Location* ignored)
1126 Session::locations_changed ()
1128 _locations.apply (*this, &Session::handle_locations_changed);
1132 Session::handle_locations_changed (Locations::LocationList& locations)
1134 Locations::LocationList::iterator i;
1136 bool set_loop = false;
1137 bool set_punch = false;
1139 for (i = locations.begin(); i != locations.end(); ++i) {
1143 if (location->is_auto_punch()) {
1144 set_auto_punch_location (location);
1147 if (location->is_auto_loop()) {
1148 set_auto_loop_location (location);
1155 set_auto_loop_location (0);
1158 set_auto_punch_location (0);
1165 Session::enable_record ()
1167 /* XXX really atomic compare+swap here */
1168 if (g_atomic_int_get (&_record_status) != Recording) {
1169 g_atomic_int_set (&_record_status, Recording);
1170 _last_record_location = _transport_frame;
1171 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1173 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1174 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1175 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1176 if ((*i)->record_enabled ()) {
1177 (*i)->monitor_input (true);
1182 RecordStateChanged ();
1187 Session::disable_record (bool rt_context, bool force)
1191 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1193 if (!Config->get_latched_record_enable () || force) {
1194 g_atomic_int_set (&_record_status, Disabled);
1196 if (rs == Recording) {
1197 g_atomic_int_set (&_record_status, Enabled);
1201 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1203 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1204 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1206 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1207 if ((*i)->record_enabled ()) {
1208 (*i)->monitor_input (false);
1213 RecordStateChanged (); /* emit signal */
1216 remove_pending_capture_state ();
1222 Session::step_back_from_record ()
1224 g_atomic_int_set (&_record_status, Enabled);
1226 if (Config->get_monitoring_model() == HardwareMonitoring) {
1227 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1229 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1230 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1231 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1232 (*i)->monitor_input (false);
1239 Session::maybe_enable_record ()
1241 g_atomic_int_set (&_record_status, Enabled);
1243 /* this function is currently called from somewhere other than an RT thread.
1244 this save_state() call therefore doesn't impact anything.
1247 save_state ("", true);
1249 if (_transport_speed) {
1250 if (!Config->get_punch_in()) {
1254 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1255 RecordStateChanged (); /* EMIT SIGNAL */
1262 Session::audible_frame () const
1268 /* the first of these two possible settings for "offset"
1269 mean that the audible frame is stationary until
1270 audio emerges from the latency compensation
1273 the second means that the audible frame is stationary
1274 until audio would emerge from a physical port
1275 in the absence of any plugin latency compensation
1278 offset = _worst_output_latency;
1280 if (offset > current_block_size) {
1281 offset -= current_block_size;
1283 /* XXX is this correct? if we have no external
1284 physical connections and everything is internal
1285 then surely this is zero? still, how
1286 likely is that anyway?
1288 offset = current_block_size;
1291 if (synced_to_jack()) {
1292 tf = _engine.transport_frame();
1294 tf = _transport_frame;
1297 if (_transport_speed == 0) {
1307 if (!non_realtime_work_pending()) {
1311 /* take latency into account */
1320 Session::set_frame_rate (nframes_t frames_per_second)
1322 /** \fn void Session::set_frame_size(nframes_t)
1323 the AudioEngine object that calls this guarantees
1324 that it will not be called while we are also in
1325 ::process(). Its fine to do things that block
1329 _base_frame_rate = frames_per_second;
1333 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1335 // XXX we need some equivalent to this, somehow
1336 // SndFileSource::setup_standard_crossfades (frames_per_second);
1340 /* XXX need to reset/reinstantiate all LADSPA plugins */
1344 Session::set_block_size (nframes_t nframes)
1346 /* the AudioEngine guarantees
1347 that it will not be called while we are also in
1348 ::process(). It is therefore fine to do things that block
1353 vector<Sample*>::iterator i;
1356 current_block_size = nframes;
1358 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1362 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1366 _passthru_buffers.clear ();
1367 _silent_buffers.clear ();
1369 ensure_passthru_buffers (np);
1371 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1375 #ifdef NO_POSIX_MEMALIGN
1376 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1378 posix_memalign((void **)&buf,16,current_block_size * 4);
1382 memset (*i, 0, sizeof (Sample) * current_block_size);
1386 if (_gain_automation_buffer) {
1387 delete [] _gain_automation_buffer;
1389 _gain_automation_buffer = new gain_t[nframes];
1391 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1393 boost::shared_ptr<RouteList> r = routes.reader ();
1395 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1396 (*i)->set_block_size (nframes);
1399 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1400 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1401 (*i)->set_block_size (nframes);
1404 set_worst_io_latencies ();
1409 Session::set_default_fade (float steepness, float fade_msecs)
1412 nframes_t fade_frames;
1414 /* Don't allow fade of less 1 frame */
1416 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1423 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1427 default_fade_msecs = fade_msecs;
1428 default_fade_steepness = steepness;
1431 // jlc, WTF is this!
1432 Glib::RWLock::ReaderLock lm (route_lock);
1433 AudioRegion::set_default_fade (steepness, fade_frames);
1438 /* XXX have to do this at some point */
1439 /* foreach region using default fade, reset, then
1440 refill_all_diskstream_buffers ();
1445 struct RouteSorter {
1446 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1447 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1449 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1452 if (r1->fed_by.empty()) {
1453 if (r2->fed_by.empty()) {
1454 /* no ardour-based connections inbound to either route. just use signal order */
1455 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1457 /* r2 has connections, r1 does not; run r1 early */
1461 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1468 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1470 shared_ptr<Route> r2;
1472 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1473 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1477 /* make a copy of the existing list of routes that feed r1 */
1479 set<shared_ptr<Route> > existing = r1->fed_by;
1481 /* for each route that feeds r1, recurse, marking it as feeding
1485 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1488 /* r2 is a route that feeds r1 which somehow feeds base. mark
1489 base as being fed by r2
1492 rbase->fed_by.insert (r2);
1496 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1500 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1504 /* now recurse, so that we can mark base as being fed by
1505 all routes that feed r2
1508 trace_terminal (r2, rbase);
1515 Session::resort_routes ()
1517 /* don't do anything here with signals emitted
1518 by Routes while we are being destroyed.
1521 if (_state_of_the_state & Deletion) {
1528 RCUWriter<RouteList> writer (routes);
1529 shared_ptr<RouteList> r = writer.get_copy ();
1530 resort_routes_using (r);
1531 /* writer goes out of scope and forces update */
1536 Session::resort_routes_using (shared_ptr<RouteList> r)
1538 RouteList::iterator i, j;
1540 for (i = r->begin(); i != r->end(); ++i) {
1542 (*i)->fed_by.clear ();
1544 for (j = r->begin(); j != r->end(); ++j) {
1546 /* although routes can feed themselves, it will
1547 cause an endless recursive descent if we
1548 detect it. so don't bother checking for
1556 if ((*j)->feeds (*i)) {
1557 (*i)->fed_by.insert (*j);
1562 for (i = r->begin(); i != r->end(); ++i) {
1563 trace_terminal (*i, *i);
1569 /* don't leave dangling references to routes in Route::fed_by */
1571 for (i = r->begin(); i != r->end(); ++i) {
1572 (*i)->fed_by.clear ();
1576 cerr << "finished route resort\n";
1578 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1579 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1586 list<boost::shared_ptr<AudioTrack> >
1587 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1589 char track_name[32];
1590 uint32_t track_id = 0;
1592 uint32_t channels_used = 0;
1594 RouteList new_routes;
1595 list<boost::shared_ptr<AudioTrack> > ret;
1597 /* count existing audio tracks */
1600 shared_ptr<RouteList> r = routes.reader ();
1602 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1603 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1604 if (!(*i)->hidden()) {
1606 channels_used += (*i)->n_inputs();
1612 vector<string> physinputs;
1613 vector<string> physoutputs;
1614 uint32_t nphysical_in;
1615 uint32_t nphysical_out;
1617 _engine.get_physical_outputs (physoutputs);
1618 _engine.get_physical_inputs (physinputs);
1622 /* check for duplicate route names, since we might have pre-existing
1623 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1624 save, close,restart,add new route - first named route is now
1632 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1634 if (route_by_name (track_name) == 0) {
1638 } while (track_id < (UINT_MAX-1));
1640 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1641 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1646 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1647 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1653 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1655 if (track->ensure_io (input_channels, output_channels, false, this)) {
1656 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1657 input_channels, output_channels)
1662 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1666 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1667 port = physinputs[(channels_used+x)%nphysical_in];
1670 if (port.length() && track->connect_input (track->input (x), port, this)) {
1676 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1680 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1681 port = physoutputs[(channels_used+x)%nphysical_out];
1682 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1684 port = _master_out->input (x%_master_out->n_inputs())->name();
1688 if (port.length() && track->connect_output (track->output (x), port, this)) {
1693 channels_used += track->n_inputs ();
1696 vector<string> cports;
1697 uint32_t ni = _control_out->n_inputs();
1699 for (n = 0; n < ni; ++n) {
1700 cports.push_back (_control_out->input(n)->name());
1703 track->set_control_outs (cports);
1706 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1707 track->set_remote_control_id (ntracks());
1709 new_routes.push_back (track);
1710 ret.push_back (track);
1713 catch (failed_constructor &err) {
1714 error << _("Session: could not create new audio track.") << endmsg;
1715 // XXX should we delete the tracks already created?
1723 if (!new_routes.empty()) {
1724 add_routes (new_routes, false);
1725 save_state (_current_snapshot_name);
1732 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1735 uint32_t bus_id = 1;
1740 /* count existing audio busses */
1743 shared_ptr<RouteList> r = routes.reader ();
1745 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1746 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1747 if (!(*i)->hidden()) {
1754 vector<string> physinputs;
1755 vector<string> physoutputs;
1757 _engine.get_physical_outputs (physoutputs);
1758 _engine.get_physical_inputs (physinputs);
1765 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1767 if (route_by_name (bus_name) == 0) {
1771 } while (bus_id < (UINT_MAX-1));
1774 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1776 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1777 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1778 input_channels, output_channels)
1782 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs(); ++x) {
1786 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1787 port = physinputs[((n+x)%n_physical_inputs)];
1790 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1795 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs(); ++x) {
1799 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1800 port = physoutputs[((n+x)%n_physical_outputs)];
1801 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1803 port = _master_out->input (x%_master_out->n_inputs())->name();
1807 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1813 vector<string> cports;
1814 uint32_t ni = _control_out->n_inputs();
1816 for (uint32_t n = 0; n < ni; ++n) {
1817 cports.push_back (_control_out->input(n)->name());
1819 bus->set_control_outs (cports);
1822 ret.push_back (bus);
1826 catch (failed_constructor &err) {
1827 error << _("Session: could not create new audio route.") << endmsg;
1836 add_routes (ret, false);
1837 save_state (_current_snapshot_name);
1845 Session::add_routes (RouteList& new_routes, bool save)
1848 RCUWriter<RouteList> writer (routes);
1849 shared_ptr<RouteList> r = writer.get_copy ();
1850 r->insert (r->end(), new_routes.begin(), new_routes.end());
1851 resort_routes_using (r);
1854 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1856 boost::weak_ptr<Route> wpr (*x);
1858 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1859 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1860 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1861 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1863 if ((*x)->master()) {
1867 if ((*x)->control()) {
1868 _control_out = (*x);
1875 save_state (_current_snapshot_name);
1878 RouteAdded (new_routes); /* EMIT SIGNAL */
1882 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1884 /* need to do this in case we're rolling at the time, to prevent false underruns */
1885 dstream->do_refill_with_alloc();
1888 RCUWriter<DiskstreamList> writer (diskstreams);
1889 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1890 ds->push_back (dstream);
1893 dstream->set_block_size (current_block_size);
1895 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1896 /* this will connect to future changes, and check the current length */
1897 diskstream_playlist_changed (dstream);
1899 dstream->prepare ();
1903 Session::remove_route (shared_ptr<Route> route)
1906 RCUWriter<RouteList> writer (routes);
1907 shared_ptr<RouteList> rs = writer.get_copy ();
1911 /* deleting the master out seems like a dumb
1912 idea, but its more of a UI policy issue
1916 if (route == _master_out) {
1917 _master_out = shared_ptr<Route> ();
1920 if (route == _control_out) {
1921 _control_out = shared_ptr<Route> ();
1923 /* cancel control outs for all routes */
1925 vector<string> empty;
1927 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1928 (*r)->set_control_outs (empty);
1932 update_route_solo_state ();
1934 /* writer goes out of scope, forces route list update */
1937 // FIXME: audio specific
1939 boost::shared_ptr<AudioDiskstream> ds;
1941 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1942 ds = at->audio_diskstream();
1948 RCUWriter<DiskstreamList> dsl (diskstreams);
1949 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1954 find_current_end ();
1956 update_latency_compensation (false, false);
1959 // We need to disconnect the routes inputs and outputs
1960 route->disconnect_inputs(NULL);
1961 route->disconnect_outputs(NULL);
1963 /* get rid of it from the dead wood collection in the route list manager */
1965 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1969 /* try to cause everyone to drop their references */
1971 route->drop_references ();
1973 /* save the new state of the world */
1975 if (save_state (_current_snapshot_name)) {
1976 save_history (_current_snapshot_name);
1981 Session::route_mute_changed (void* src)
1987 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
1989 if (solo_update_disabled) {
1995 boost::shared_ptr<Route> route = wpr.lock ();
1998 /* should not happen */
1999 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2003 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2005 shared_ptr<RouteList> r = routes.reader ();
2007 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2009 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2013 /* don't mess with busses */
2015 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2021 /* don't mess with tracks */
2023 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2028 if ((*i) != route &&
2029 ((*i)->mix_group () == 0 ||
2030 (*i)->mix_group () != route->mix_group () ||
2031 !route->mix_group ()->is_active())) {
2033 if ((*i)->soloed()) {
2035 /* if its already soloed, and solo latching is enabled,
2036 then leave it as it is.
2039 if (Config->get_solo_latched()) {
2046 solo_update_disabled = true;
2047 (*i)->set_solo (false, src);
2048 solo_update_disabled = false;
2052 bool something_soloed = false;
2053 bool same_thing_soloed = false;
2054 bool signal = false;
2056 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2057 if ((*i)->soloed()) {
2058 something_soloed = true;
2059 if (dynamic_cast<AudioTrack*>((*i).get())) {
2061 same_thing_soloed = true;
2066 same_thing_soloed = true;
2074 if (something_soloed != currently_soloing) {
2076 currently_soloing = something_soloed;
2079 modify_solo_mute (is_track, same_thing_soloed);
2082 SoloActive (currently_soloing);
2089 Session::update_route_solo_state ()
2092 bool is_track = false;
2093 bool signal = false;
2095 /* caller must hold RouteLock */
2097 /* this is where we actually implement solo by changing
2098 the solo mute setting of each track.
2101 shared_ptr<RouteList> r = routes.reader ();
2103 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2104 if ((*i)->soloed()) {
2106 if (dynamic_cast<AudioTrack*>((*i).get())) {
2113 if (mute != currently_soloing) {
2115 currently_soloing = mute;
2118 if (!is_track && !mute) {
2120 /* nothing is soloed */
2122 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2123 (*i)->set_solo_mute (false);
2133 modify_solo_mute (is_track, mute);
2136 SoloActive (currently_soloing);
2141 Session::modify_solo_mute (bool is_track, bool mute)
2143 shared_ptr<RouteList> r = routes.reader ();
2145 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2149 /* only alter track solo mute */
2151 if (dynamic_cast<AudioTrack*>((*i).get())) {
2152 if ((*i)->soloed()) {
2153 (*i)->set_solo_mute (!mute);
2155 (*i)->set_solo_mute (mute);
2161 /* only alter bus solo mute */
2163 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2165 if ((*i)->soloed()) {
2167 (*i)->set_solo_mute (false);
2171 /* don't mute master or control outs
2172 in response to another bus solo
2175 if ((*i) != _master_out &&
2176 (*i) != _control_out) {
2177 (*i)->set_solo_mute (mute);
2188 Session::catch_up_on_solo ()
2190 /* this is called after set_state() to catch the full solo
2191 state, which can't be correctly determined on a per-route
2192 basis, but needs the global overview that only the session
2195 update_route_solo_state();
2199 Session::route_by_name (string name)
2201 shared_ptr<RouteList> r = routes.reader ();
2203 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2204 if ((*i)->name() == name) {
2209 return shared_ptr<Route> ((Route*) 0);
2213 Session::route_by_id (PBD::ID id)
2215 shared_ptr<RouteList> r = routes.reader ();
2217 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2218 if ((*i)->id() == id) {
2223 return shared_ptr<Route> ((Route*) 0);
2227 Session::route_by_remote_id (uint32_t id)
2229 shared_ptr<RouteList> r = routes.reader ();
2231 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2232 if ((*i)->remote_control_id() == id) {
2237 return shared_ptr<Route> ((Route*) 0);
2241 Session::find_current_end ()
2243 if (_state_of_the_state & Loading) {
2247 nframes_t max = get_maximum_extent ();
2249 if (max > end_location->end()) {
2250 end_location->set_end (max);
2252 DurationChanged(); /* EMIT SIGNAL */
2257 Session::get_maximum_extent () const
2262 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2264 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2265 Playlist* pl = (*i)->playlist();
2266 if ((me = pl->get_maximum_extent()) > max) {
2274 boost::shared_ptr<Diskstream>
2275 Session::diskstream_by_name (string name)
2277 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2279 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2280 if ((*i)->name() == name) {
2285 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2288 boost::shared_ptr<Diskstream>
2289 Session::diskstream_by_id (const PBD::ID& id)
2291 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2293 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2294 if ((*i)->id() == id) {
2299 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2302 /* AudioRegion management */
2305 Session::new_region_name (string old)
2307 string::size_type last_period;
2309 string::size_type len = old.length() + 64;
2312 if ((last_period = old.find_last_of ('.')) == string::npos) {
2314 /* no period present - add one explicitly */
2317 last_period = old.length() - 1;
2322 number = atoi (old.substr (last_period+1).c_str());
2326 while (number < (UINT_MAX-1)) {
2328 AudioRegionList::const_iterator i;
2333 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2336 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2337 if (i->second->name() == sbuf) {
2342 if (i == audio_regions.end()) {
2347 if (number != (UINT_MAX-1)) {
2351 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2356 Session::region_name (string& result, string base, bool newlevel) const
2363 Glib::Mutex::Lock lm (region_lock);
2365 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2373 /* XXX this is going to be slow. optimize me later */
2378 string::size_type pos;
2380 pos = base.find_last_of ('.');
2382 /* pos may be npos, but then we just use entire base */
2384 subbase = base.substr (0, pos);
2388 bool name_taken = true;
2391 Glib::Mutex::Lock lm (region_lock);
2393 for (int n = 1; n < 5000; ++n) {
2396 snprintf (buf, sizeof (buf), ".%d", n);
2401 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2402 if (i->second->name() == result) {
2415 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2423 Session::add_region (boost::shared_ptr<Region> region)
2425 boost::shared_ptr<AudioRegion> ar;
2426 boost::shared_ptr<AudioRegion> oar;
2430 Glib::Mutex::Lock lm (region_lock);
2432 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2434 AudioRegionList::iterator x;
2436 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2438 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2440 if (ar->region_list_equivalent (oar)) {
2445 if (x == audio_regions.end()) {
2447 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2449 entry.first = region->id();
2452 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2464 fatal << _("programming error: ")
2465 << X_("unknown region type passed to Session::add_region()")
2472 /* mark dirty because something has changed even if we didn't
2473 add the region to the region list.
2479 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2480 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2481 AudioRegionAdded (ar); /* EMIT SIGNAL */
2486 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2488 boost::shared_ptr<Region> region (weak_region.lock ());
2494 if (what_changed & Region::HiddenChanged) {
2495 /* relay hidden changes */
2496 RegionHiddenChange (region);
2501 Session::remove_region (boost::weak_ptr<Region> weak_region)
2503 AudioRegionList::iterator i;
2504 boost::shared_ptr<Region> region (weak_region.lock ());
2510 boost::shared_ptr<AudioRegion> ar;
2511 bool removed = false;
2514 Glib::Mutex::Lock lm (region_lock);
2516 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2517 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2518 audio_regions.erase (i);
2524 fatal << _("programming error: ")
2525 << X_("unknown region type passed to Session::remove_region()")
2531 /* mark dirty because something has changed even if we didn't
2532 remove the region from the region list.
2538 AudioRegionRemoved (ar); /* EMIT SIGNAL */
2542 boost::shared_ptr<AudioRegion>
2543 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion const> child)
2545 AudioRegionList::iterator i;
2546 boost::shared_ptr<AudioRegion> region;
2547 Glib::Mutex::Lock lm (region_lock);
2549 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2553 if (region->whole_file()) {
2555 if (child->source_equivalent (region)) {
2561 return boost::shared_ptr<AudioRegion> ();
2565 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2567 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2568 (*i)->get_region_list_equivalent_regions (region, result);
2572 Session::destroy_region (boost::shared_ptr<Region> region)
2574 vector<boost::shared_ptr<Source> > srcs;
2577 boost::shared_ptr<AudioRegion> aregion;
2579 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2583 if (aregion->playlist()) {
2584 aregion->playlist()->destroy_region (region);
2587 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2588 srcs.push_back (aregion->source (n));
2592 region->drop_references ();
2594 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2596 if (!(*i)->used()) {
2597 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2600 (afs)->mark_for_remove ();
2603 (*i)->drop_references ();
2605 cerr << "source was not used by any playlist\n";
2613 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2615 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2616 destroy_region (*i);
2622 Session::remove_last_capture ()
2624 list<boost::shared_ptr<Region> > r;
2626 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2628 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2629 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2632 r.insert (r.end(), l.begin(), l.end());
2637 destroy_regions (r);
2642 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2648 /* Source Management */
2651 Session::add_source (boost::shared_ptr<Source> source)
2653 boost::shared_ptr<AudioFileSource> afs;
2655 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2657 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2658 pair<AudioSourceList::iterator,bool> result;
2660 entry.first = source->id();
2664 Glib::Mutex::Lock lm (audio_source_lock);
2665 result = audio_sources.insert (entry);
2668 if (!result.second) {
2669 cerr << "\tNOT inserted ? " << result.second << endl;
2672 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2675 SourceAdded (source); /* EMIT SIGNAL */
2677 cerr << "\tNOT AUDIO FILE\n";
2682 Session::remove_source (boost::weak_ptr<Source> src)
2684 AudioSourceList::iterator i;
2685 boost::shared_ptr<Source> source = src.lock();
2692 Glib::Mutex::Lock lm (audio_source_lock);
2694 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2695 audio_sources.erase (i);
2699 if (!_state_of_the_state & InCleanup) {
2701 /* save state so we don't end up with a session file
2702 referring to non-existent sources.
2705 save_state (_current_snapshot_name);
2708 SourceRemoved(source); /* EMIT SIGNAL */
2711 boost::shared_ptr<Source>
2712 Session::source_by_id (const PBD::ID& id)
2714 Glib::Mutex::Lock lm (audio_source_lock);
2715 AudioSourceList::iterator i;
2716 boost::shared_ptr<Source> source;
2718 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2722 /* XXX search MIDI or other searches here */
2728 Session::peak_path_from_audio_path (string audio_path) const
2733 res += PBD::basename_nosuffix (audio_path);
2740 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2743 string old_basename = PBD::basename_nosuffix (oldname);
2744 string new_legalized = legalize_for_path (newname);
2746 /* note: we know (or assume) the old path is already valid */
2750 /* destructive file sources have a name of the form:
2752 /path/to/Tnnnn-NAME(%[LR])?.wav
2754 the task here is to replace NAME with the new name.
2757 /* find last slash */
2761 string::size_type slash;
2762 string::size_type dash;
2764 if ((slash = path.find_last_of ('/')) == string::npos) {
2768 dir = path.substr (0, slash+1);
2770 /* '-' is not a legal character for the NAME part of the path */
2772 if ((dash = path.find_last_of ('-')) == string::npos) {
2776 prefix = path.substr (slash+1, dash-(slash+1));
2781 path += new_legalized;
2782 path += ".wav"; /* XXX gag me with a spoon */
2786 /* non-destructive file sources have a name of the form:
2788 /path/to/NAME-nnnnn(%[LR])?.wav
2790 the task here is to replace NAME with the new name.
2795 string::size_type slash;
2796 string::size_type dash;
2797 string::size_type postfix;
2799 /* find last slash */
2801 if ((slash = path.find_last_of ('/')) == string::npos) {
2805 dir = path.substr (0, slash+1);
2807 /* '-' is not a legal character for the NAME part of the path */
2809 if ((dash = path.find_last_of ('-')) == string::npos) {
2813 suffix = path.substr (dash+1);
2815 // Suffix is now everything after the dash. Now we need to eliminate
2816 // the nnnnn part, which is done by either finding a '%' or a '.'
2818 postfix = suffix.find_last_of ("%");
2819 if (postfix == string::npos) {
2820 postfix = suffix.find_last_of ('.');
2823 if (postfix != string::npos) {
2824 suffix = suffix.substr (postfix);
2826 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2830 const uint32_t limit = 10000;
2831 char buf[PATH_MAX+1];
2833 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2835 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2837 if (access (buf, F_OK) != 0) {
2845 error << "FATAL ERROR! Could not find a " << endl;
2854 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2858 char buf[PATH_MAX+1];
2859 const uint32_t limit = 10000;
2863 legalized = legalize_for_path (name);
2865 /* find a "version" of the file name that doesn't exist in
2866 any of the possible directories.
2869 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2871 vector<space_and_path>::iterator i;
2872 uint32_t existing = 0;
2874 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2878 spath += sound_dir (false);
2882 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2883 } else if (nchan == 2) {
2885 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2887 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2889 } else if (nchan < 26) {
2890 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2892 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2900 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2901 } else if (nchan == 2) {
2903 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2905 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2907 } else if (nchan < 26) {
2908 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2910 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2914 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2920 if (existing == 0) {
2925 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2926 throw failed_constructor();
2930 /* we now have a unique name for the file, but figure out where to
2936 spath = discover_best_sound_dir ();
2938 string::size_type pos = foo.find_last_of ('/');
2940 if (pos == string::npos) {
2943 spath += foo.substr (pos + 1);
2949 boost::shared_ptr<AudioFileSource>
2950 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2952 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2953 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
2956 /* Playlist management */
2959 Session::playlist_by_name (string name)
2961 Glib::Mutex::Lock lm (playlist_lock);
2962 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2963 if ((*i)->name() == name) {
2967 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2968 if ((*i)->name() == name) {
2976 Session::add_playlist (Playlist* playlist)
2978 if (playlist->hidden()) {
2983 Glib::Mutex::Lock lm (playlist_lock);
2984 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2985 playlists.insert (playlists.begin(), playlist);
2987 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2988 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
2994 PlaylistAdded (playlist); /* EMIT SIGNAL */
2998 Session::get_playlists (vector<Playlist*>& s)
3001 Glib::Mutex::Lock lm (playlist_lock);
3002 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3005 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3012 Session::track_playlist (Playlist* pl, bool inuse)
3014 PlaylistList::iterator x;
3017 Glib::Mutex::Lock lm (playlist_lock);
3020 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3022 unused_playlists.insert (pl);
3024 if ((x = playlists.find (pl)) != playlists.end()) {
3025 playlists.erase (x);
3030 //cerr << "shifting playlist to used: " << pl->name() << endl;
3032 playlists.insert (pl);
3034 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3035 unused_playlists.erase (x);
3042 Session::remove_playlist (Playlist* playlist)
3044 if (_state_of_the_state & Deletion) {
3049 Glib::Mutex::Lock lm (playlist_lock);
3050 // cerr << "removing playlist: " << playlist->name() << endl;
3052 PlaylistList::iterator i;
3054 i = find (playlists.begin(), playlists.end(), playlist);
3056 if (i != playlists.end()) {
3057 playlists.erase (i);
3060 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3061 if (i != unused_playlists.end()) {
3062 unused_playlists.erase (i);
3069 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3073 Session::set_audition (boost::shared_ptr<Region> r)
3075 pending_audition_region = r;
3076 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3077 schedule_butler_transport_work ();
3081 Session::audition_playlist ()
3083 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3084 ev->region.reset ();
3089 Session::non_realtime_set_audition ()
3091 if (!pending_audition_region) {
3092 auditioner->audition_current_playlist ();
3094 auditioner->audition_region (pending_audition_region);
3095 pending_audition_region.reset ();
3097 AuditionActive (true); /* EMIT SIGNAL */
3101 Session::audition_region (boost::shared_ptr<Region> r)
3103 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3109 Session::cancel_audition ()
3111 if (auditioner->active()) {
3112 auditioner->cancel_audition ();
3113 AuditionActive (false); /* EMIT SIGNAL */
3118 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3120 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3124 Session::remove_empty_sounds ()
3126 PathScanner scanner;
3128 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3130 Glib::Mutex::Lock lm (audio_source_lock);
3132 regex_t compiled_tape_track_pattern;
3135 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3139 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3141 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3145 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3147 /* never remove files that appear to be a tape track */
3149 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3154 if (AudioFileSource::is_empty (*this, *(*i))) {
3156 unlink ((*i)->c_str());
3158 string peak_path = peak_path_from_audio_path (**i);
3159 unlink (peak_path.c_str());
3165 delete possible_audiofiles;
3169 Session::is_auditioning () const
3171 /* can be called before we have an auditioner object */
3173 return auditioner->active();
3180 Session::set_all_solo (bool yn)
3182 shared_ptr<RouteList> r = routes.reader ();
3184 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3185 if (!(*i)->hidden()) {
3186 (*i)->set_solo (yn, this);
3194 Session::set_all_mute (bool yn)
3196 shared_ptr<RouteList> r = routes.reader ();
3198 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3199 if (!(*i)->hidden()) {
3200 (*i)->set_mute (yn, this);
3208 Session::n_diskstreams () const
3212 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3214 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3215 if (!(*i)->hidden()) {
3223 Session::graph_reordered ()
3225 /* don't do this stuff if we are setting up connections
3226 from a set_state() call.
3229 if (_state_of_the_state & InitialConnecting) {
3235 /* force all diskstreams to update their capture offset values to
3236 reflect any changes in latencies within the graph.
3239 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3241 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3242 (*i)->set_capture_offset ();
3247 Session::record_disenable_all ()
3249 record_enable_change_all (false);
3253 Session::record_enable_all ()
3255 record_enable_change_all (true);
3259 Session::record_enable_change_all (bool yn)
3261 shared_ptr<RouteList> r = routes.reader ();
3263 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3266 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3267 at->set_record_enable (yn, this);
3271 /* since we don't keep rec-enable state, don't mark session dirty */
3275 Session::add_redirect (Redirect* redirect)
3279 PortInsert* port_insert;
3280 PluginInsert* plugin_insert;
3282 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3283 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3284 _port_inserts.insert (_port_inserts.begin(), port_insert);
3285 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3286 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3288 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3291 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3292 _sends.insert (_sends.begin(), send);
3294 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3298 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3304 Session::remove_redirect (Redirect* redirect)
3308 PortInsert* port_insert;
3309 PluginInsert* plugin_insert;
3311 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3312 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3313 _port_inserts.remove (port_insert);
3314 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3315 _plugin_inserts.remove (plugin_insert);
3317 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3320 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3321 _sends.remove (send);
3323 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3331 Session::available_capture_duration ()
3333 float sample_bytes_on_disk;
3335 switch (Config->get_native_file_data_format()) {
3337 sample_bytes_on_disk = 4;
3341 sample_bytes_on_disk = 3;
3345 double scale = 4096.0 / sample_bytes_on_disk;
3347 if (_total_free_4k_blocks * scale > (double) max_frames) {
3351 return (nframes_t) floor (_total_free_4k_blocks * scale);
3355 Session::add_connection (ARDOUR::Connection* connection)
3358 Glib::Mutex::Lock guard (connection_lock);
3359 _connections.push_back (connection);
3362 ConnectionAdded (connection); /* EMIT SIGNAL */
3368 Session::remove_connection (ARDOUR::Connection* connection)
3370 bool removed = false;
3373 Glib::Mutex::Lock guard (connection_lock);
3374 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3376 if (i != _connections.end()) {
3377 _connections.erase (i);
3383 ConnectionRemoved (connection); /* EMIT SIGNAL */
3389 ARDOUR::Connection *
3390 Session::connection_by_name (string name) const
3392 Glib::Mutex::Lock lm (connection_lock);
3394 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3395 if ((*i)->name() == name) {
3404 Session::tempo_map_changed (Change ignored)
3411 Session::ensure_passthru_buffers (uint32_t howmany)
3413 while (howmany > _passthru_buffers.size()) {
3415 #ifdef NO_POSIX_MEMALIGN
3416 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3418 posix_memalign((void **)&p,16,current_block_size * 4);
3420 _passthru_buffers.push_back (p);
3424 #ifdef NO_POSIX_MEMALIGN
3425 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3427 posix_memalign((void **)&p,16,current_block_size * 4);
3429 memset (p, 0, sizeof (Sample) * current_block_size);
3430 _silent_buffers.push_back (p);
3434 #ifdef NO_POSIX_MEMALIGN
3435 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3437 posix_memalign((void **)&p,16,current_block_size * 4);
3439 memset (p, 0, sizeof (Sample) * current_block_size);
3440 _send_buffers.push_back (p);
3443 allocate_pan_automation_buffers (current_block_size, howmany, false);
3447 Session::next_send_name ()
3450 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3455 Session::next_insert_name ()
3458 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3462 /* Named Selection management */
3465 Session::named_selection_by_name (string name)
3467 Glib::Mutex::Lock lm (named_selection_lock);
3468 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3469 if ((*i)->name == name) {
3477 Session::add_named_selection (NamedSelection* named_selection)
3480 Glib::Mutex::Lock lm (named_selection_lock);
3481 named_selections.insert (named_selections.begin(), named_selection);
3486 NamedSelectionAdded (); /* EMIT SIGNAL */
3490 Session::remove_named_selection (NamedSelection* named_selection)
3492 bool removed = false;
3495 Glib::Mutex::Lock lm (named_selection_lock);
3497 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3499 if (i != named_selections.end()) {
3501 named_selections.erase (i);
3508 NamedSelectionRemoved (); /* EMIT SIGNAL */
3513 Session::reset_native_file_format ()
3515 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3517 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3518 (*i)->reset_write_sources (false);
3523 Session::route_name_unique (string n) const
3525 shared_ptr<RouteList> r = routes.reader ();
3527 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3528 if ((*i)->name() == n) {
3537 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3539 return fs->move_to_trash (dead_sound_dir_name);
3543 Session::n_playlists () const
3545 Glib::Mutex::Lock lm (playlist_lock);
3546 return playlists.size();
3550 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3552 if (!force && howmany <= _npan_buffers) {
3556 if (_pan_automation_buffer) {
3558 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3559 delete [] _pan_automation_buffer[i];
3562 delete [] _pan_automation_buffer;
3565 _pan_automation_buffer = new pan_t*[howmany];
3567 for (uint32_t i = 0; i < howmany; ++i) {
3568 _pan_automation_buffer[i] = new pan_t[nframes];
3571 _npan_buffers = howmany;
3575 Session::freeze (InterThreadInfo& itt)
3577 shared_ptr<RouteList> r = routes.reader ();
3579 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3583 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3584 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3595 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3596 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3600 boost::shared_ptr<AudioFileSource> fsource;
3602 char buf[PATH_MAX+1];
3606 nframes_t this_chunk;
3608 vector<Sample*> buffers;
3610 // any bigger than this seems to cause stack overflows in called functions
3611 const nframes_t chunk_size = (128 * 1024)/4;
3613 g_atomic_int_set (&processing_prohibited, 1);
3615 /* call tree *MUST* hold route_lock */
3617 if ((playlist = track.diskstream()->playlist()) == 0) {
3621 /* external redirects will be a problem */
3623 if (track.has_external_redirects()) {
3627 nchans = track.audio_diskstream()->n_channels();
3629 dir = discover_best_sound_dir ();
3631 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3633 for (x = 0; x < 99999; ++x) {
3634 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3635 if (access (buf, F_OK) != 0) {
3641 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3646 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3649 catch (failed_constructor& err) {
3650 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3654 srcs.push_back (fsource);
3657 /* XXX need to flush all redirects */
3662 /* create a set of reasonably-sized buffers */
3664 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3666 #ifdef NO_POSIX_MEMALIGN
3667 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3669 posix_memalign((void **)&b,16,chunk_size * 4);
3671 buffers.push_back (b);
3674 while (to_do && !itt.cancel) {
3676 this_chunk = min (to_do, chunk_size);
3678 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3683 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3684 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3687 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3693 start += this_chunk;
3694 to_do -= this_chunk;
3696 itt.progress = (float) (1.0 - ((double) to_do / len));
3705 xnow = localtime (&now);
3707 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3708 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3711 afs->update_header (position, *xnow, now);
3715 /* build peakfile for new source */
3717 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3718 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3720 afs->build_peaks ();
3724 /* construct a region to represent the bounced material */
3726 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3727 region_name_from_path (srcs.front()->name()));
3734 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3735 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3738 afs->mark_for_remove ();
3741 (*src)->drop_references ();
3745 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3749 g_atomic_int_set (&processing_prohibited, 0);
3757 Session::get_silent_buffers (uint32_t howmany)
3759 for (uint32_t i = 0; i < howmany; ++i) {
3760 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3762 return _silent_buffers;
3766 Session::ntracks () const
3769 shared_ptr<RouteList> r = routes.reader ();
3771 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3772 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3781 Session::nbusses () const
3784 shared_ptr<RouteList> r = routes.reader ();
3786 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3787 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3796 Session::add_automation_list(AutomationList *al)
3798 automation_lists[al->id()] = al;
3802 Session::compute_initial_length ()
3804 return _engine.frame_rate() * 60 * 5;