2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <sigc++/bind.h>
33 #include <sigc++/retype.h>
35 #include <glibmm/thread.h>
36 #include <glibmm/miscutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/audio_diskstream.h>
48 #include <ardour/utils.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/destructive_filesource.h>
53 #include <ardour/auditioner.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/redirect.h>
56 #include <ardour/send.h>
57 #include <ardour/insert.h>
58 #include <ardour/connection.h>
59 #include <ardour/slave.h>
60 #include <ardour/tempo.h>
61 #include <ardour/audio_track.h>
62 #include <ardour/cycle_timer.h>
63 #include <ardour/named_selection.h>
64 #include <ardour/crossfade.h>
65 #include <ardour/playlist.h>
66 #include <ardour/click.h>
67 #include <ardour/data_type.h>
68 #include <ardour/source_factory.h>
71 #include <ardour/osc.h>
77 using namespace ARDOUR;
79 using boost::shared_ptr;
81 const char* Session::_template_suffix = X_(".template");
82 const char* Session::_statefile_suffix = X_(".ardour");
83 const char* Session::_pending_suffix = X_(".pending");
84 const char* Session::old_sound_dir_name = X_("sounds");
85 const char* Session::sound_dir_name = X_("audiofiles");
86 const char* Session::peak_dir_name = X_("peaks");
87 const char* Session::dead_sound_dir_name = X_("dead_sounds");
88 const char* Session::interchange_dir_name = X_("interchange");
90 Session::compute_peak_t Session::compute_peak = 0;
91 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
92 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
93 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
95 sigc::signal<int> Session::AskAboutPendingState;
96 sigc::signal<void> Session::SendFeedback;
98 sigc::signal<void> Session::SMPTEOffsetChanged;
99 sigc::signal<void> Session::SMPTETypeChanged;
100 sigc::signal<void> Session::PullupChanged;
101 sigc::signal<void> Session::StartTimeChanged;
102 sigc::signal<void> Session::EndTimeChanged;
105 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
108 char buf[PATH_MAX+1];
112 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
113 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
119 /* check to see if it exists, and what it is */
121 if (stat (str.c_str(), &statbuf)) {
122 if (errno == ENOENT) {
125 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
133 /* it exists, so it must either be the name
134 of the directory, or the name of the statefile
138 if (S_ISDIR (statbuf.st_mode)) {
140 string::size_type slash = str.find_last_of ('/');
142 if (slash == string::npos) {
144 /* a subdirectory of cwd, so statefile should be ... */
150 tmp += _statefile_suffix;
154 if (stat (tmp.c_str(), &statbuf)) {
155 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
165 /* some directory someplace in the filesystem.
166 the snapshot name is the directory name
171 snapshot = str.substr (slash+1);
175 } else if (S_ISREG (statbuf.st_mode)) {
177 string::size_type slash = str.find_last_of ('/');
178 string::size_type suffix;
180 /* remove the suffix */
182 if (slash != string::npos) {
183 snapshot = str.substr (slash+1);
188 suffix = snapshot.find (_statefile_suffix);
190 if (suffix == string::npos) {
191 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
197 snapshot = snapshot.substr (0, suffix);
199 if (slash == string::npos) {
201 /* we must be in the directory where the
202 statefile lives. get it using cwd().
205 char cwd[PATH_MAX+1];
207 if (getcwd (cwd, sizeof (cwd)) == 0) {
208 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
217 /* full path to the statefile */
219 path = str.substr (0, slash);
224 /* what type of file is it? */
225 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
231 /* its the name of a new directory. get the name
235 string::size_type slash = str.find_last_of ('/');
237 if (slash == string::npos) {
239 /* no slash, just use the name, but clean it up */
241 path = legalize_for_path (str);
247 snapshot = str.substr (slash+1);
254 Session::Session (AudioEngine &eng,
256 string snapshot_name,
257 string* mix_template)
260 _mmc_port (default_mmc_port),
261 _mtc_port (default_mtc_port),
262 _midi_port (default_midi_port),
263 pending_events (2048),
264 midi_requests (128), // the size of this should match the midi request pool size
265 diskstreams (new DiskstreamList),
266 routes (new RouteList),
267 auditioner ((Auditioner*) 0),
273 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
275 n_physical_outputs = _engine.n_physical_outputs();
276 n_physical_inputs = _engine.n_physical_inputs();
278 first_stage_init (fullpath, snapshot_name);
280 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
282 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
283 cerr << "create failed\n";
284 throw failed_constructor ();
288 if (second_stage_init (new_session)) {
289 cerr << "2nd state failed\n";
290 throw failed_constructor ();
293 store_recent_sessions(_name, _path);
295 bool was_dirty = dirty();
297 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
299 Config->ParameterChanged.connect (mem_fun (*this, &Session::handle_configuration_change));
302 DirtyChanged (); /* EMIT SIGNAL */
306 Session::Session (AudioEngine &eng,
308 string snapshot_name,
309 AutoConnectOption input_ac,
310 AutoConnectOption output_ac,
311 uint32_t control_out_channels,
312 uint32_t master_out_channels,
313 uint32_t requested_physical_in,
314 uint32_t requested_physical_out,
315 jack_nframes_t initial_length)
318 _mmc_port (default_mmc_port),
319 _mtc_port (default_mtc_port),
320 _midi_port (default_midi_port),
321 pending_events (2048),
323 diskstreams (new DiskstreamList),
324 routes (new RouteList),
330 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
332 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
333 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
335 first_stage_init (fullpath, snapshot_name);
337 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
339 if (create (new_session, 0, initial_length)) {
340 throw failed_constructor ();
344 if (control_out_channels) {
345 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
352 if (master_out_channels) {
353 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
359 /* prohibit auto-connect to master, because there isn't one */
360 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
363 input_auto_connect = input_ac;
364 output_auto_connect = output_ac;
366 if (second_stage_init (new_session)) {
367 throw failed_constructor ();
370 store_recent_sessions(_name, _path);
372 bool was_dirty = dirty ();
374 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
377 DirtyChanged (); /* EMIT SIGNAL */
383 /* if we got to here, leaving pending capture state around
387 remove_pending_capture_state ();
389 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
390 _engine.remove_session ();
392 GoingAway (); /* EMIT SIGNAL */
398 /* clear history so that no references to objects are held any more */
402 /* clear state tree so that no references to objects are held any more */
408 terminate_butler_thread ();
409 terminate_midi_thread ();
411 if (click_data && click_data != default_click) {
412 delete [] click_data;
415 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
416 delete [] click_emphasis_data;
421 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
425 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
429 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
433 AudioDiskstream::free_working_buffers();
435 #undef TRACK_DESTRUCTION
436 #ifdef TRACK_DESTRUCTION
437 cerr << "delete named selections\n";
438 #endif /* TRACK_DESTRUCTION */
439 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
440 NamedSelectionList::iterator tmp;
449 #ifdef TRACK_DESTRUCTION
450 cerr << "delete playlists\n";
451 #endif /* TRACK_DESTRUCTION */
452 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
453 PlaylistList::iterator tmp;
463 #ifdef TRACK_DESTRUCTION
464 cerr << "delete audio regions\n";
465 #endif /* TRACK_DESTRUCTION */
467 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
468 i->second->drop_references ();
471 audio_regions.clear ();
473 #ifdef TRACK_DESTRUCTION
474 cerr << "delete routes\n";
475 #endif /* TRACK_DESTRUCTION */
477 RCUWriter<RouteList> writer (routes);
478 boost::shared_ptr<RouteList> r = writer.get_copy ();
479 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
480 (*i)->drop_references ();
483 /* writer goes out of scope and updates master */
488 #ifdef TRACK_DESTRUCTION
489 cerr << "delete diskstreams\n";
490 #endif /* TRACK_DESTRUCTION */
492 RCUWriter<DiskstreamList> dwriter (diskstreams);
493 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
494 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
495 (*i)->drop_references ();
499 diskstreams.flush ();
501 #ifdef TRACK_DESTRUCTION
502 cerr << "delete audio sources\n";
503 #endif /* TRACK_DESTRUCTION */
504 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
505 AudioSourceList::iterator tmp;
510 i->second->drop_references ();
515 audio_sources.clear ();
517 #ifdef TRACK_DESTRUCTION
518 cerr << "delete mix groups\n";
519 #endif /* TRACK_DESTRUCTION */
520 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
521 list<RouteGroup*>::iterator tmp;
531 #ifdef TRACK_DESTRUCTION
532 cerr << "delete edit groups\n";
533 #endif /* TRACK_DESTRUCTION */
534 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
535 list<RouteGroup*>::iterator tmp;
545 #ifdef TRACK_DESTRUCTION
546 cerr << "delete connections\n";
547 #endif /* TRACK_DESTRUCTION */
548 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
549 ConnectionList::iterator tmp;
559 if (butler_mixdown_buffer) {
560 delete [] butler_mixdown_buffer;
563 if (butler_gain_buffer) {
564 delete [] butler_gain_buffer;
567 Crossfade::set_buffer_size (0);
575 Session::set_worst_io_latencies ()
577 _worst_output_latency = 0;
578 _worst_input_latency = 0;
580 if (!_engine.connected()) {
584 boost::shared_ptr<RouteList> r = routes.reader ();
586 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
587 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
588 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
593 Session::when_engine_running ()
595 string first_physical_output;
597 /* we don't want to run execute this again */
599 first_time_running.disconnect ();
601 set_block_size (_engine.frames_per_cycle());
602 set_frame_rate (_engine.frame_rate());
604 /* every time we reconnect, recompute worst case output latencies */
606 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
608 if (synced_to_jack()) {
609 _engine.transport_stop ();
612 if (Config->get_jack_time_master()) {
613 _engine.transport_locate (_transport_frame);
621 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
623 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
625 /* existing state for Click */
627 if (_click_io->set_state (*child->children().front()) == 0) {
629 _clicking = click_requested;
633 error << _("could not setup Click I/O") << endmsg;
639 /* default state for Click */
641 first_physical_output = _engine.get_nth_physical_output (0);
643 if (first_physical_output.length()) {
644 if (_click_io->add_output_port (first_physical_output, this)) {
645 // relax, even though its an error
647 _clicking = click_requested;
653 catch (failed_constructor& err) {
654 error << _("cannot setup Click I/O") << endmsg;
657 set_worst_io_latencies ();
660 ControlChanged (Clicking); /* EMIT SIGNAL */
663 if (auditioner == 0) {
665 /* we delay creating the auditioner till now because
666 it makes its own connections to ports named
667 in the ARDOUR_RC config file. the engine has
668 to be running for this to work.
672 auditioner.reset (new Auditioner (*this));
675 catch (failed_constructor& err) {
676 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
680 /* Create a set of Connection objects that map
681 to the physical outputs currently available
686 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
688 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
690 Connection* c = new OutputConnection (buf, true);
693 c->add_connection (0, _engine.get_nth_physical_output (np));
698 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
700 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
702 Connection* c = new InputConnection (buf, true);
705 c->add_connection (0, _engine.get_nth_physical_input (np));
712 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
714 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
716 Connection* c = new OutputConnection (buf, true);
720 c->add_connection (0, _engine.get_nth_physical_output (np));
721 c->add_connection (1, _engine.get_nth_physical_output (np+1));
726 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
728 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
730 Connection* c = new InputConnection (buf, true);
734 c->add_connection (0, _engine.get_nth_physical_input (np));
735 c->add_connection (1, _engine.get_nth_physical_input (np+1));
744 /* create master/control ports */
749 /* force the master to ignore any later call to this */
751 if (_master_out->pending_state_node) {
752 _master_out->ports_became_legal();
755 /* no panner resets till we are through */
757 _master_out->defer_pan_reset ();
759 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
760 if (_master_out->add_input_port ("", this)) {
761 error << _("cannot setup master inputs")
767 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
768 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
769 error << _("cannot setup master outputs")
776 _master_out->allow_pan_reset ();
780 Connection* c = new OutputConnection (_("Master Out"), true);
782 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
784 c->add_connection ((int) n, _master_out->input(n)->name());
791 /* catch up on send+insert cnts */
795 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
798 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
799 if (id > insert_cnt) {
807 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
810 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
817 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
819 /* hook us up to the engine */
821 _engine.set_session (this);
826 osc->set_session (*this);
829 _state_of_the_state = Clean;
831 DirtyChanged (); /* EMIT SIGNAL */
835 Session::hookup_io ()
837 /* stop graph reordering notifications from
838 causing resorts, etc.
841 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
843 /* Tell all IO objects to create their ports */
850 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
851 if (_control_out->add_input_port ("", this)) {
852 error << _("cannot setup control inputs")
858 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
859 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
860 error << _("cannot set up master outputs")
868 /* Tell all IO objects to connect themselves together */
870 IO::enable_connecting ();
872 /* Now reset all panners */
874 IO::reset_panners ();
876 /* Anyone who cares about input state, wake up and do something */
878 IOConnectionsComplete (); /* EMIT SIGNAL */
880 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
882 /* now handle the whole enchilada as if it was one
888 /* update mixer solo state */
894 Session::playlist_length_changed (Playlist* pl)
896 /* we can't just increase end_location->end() if pl->get_maximum_extent()
897 if larger. if the playlist used to be the longest playlist,
898 and its now shorter, we have to decrease end_location->end(). hence,
899 we have to iterate over all diskstreams and check the
900 playlists currently in use.
906 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
910 if ((playlist = dstream->playlist()) != 0) {
911 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
914 /* see comment in playlist_length_changed () */
919 Session::record_enabling_legal () const
921 /* this used to be in here, but survey says.... we don't need to restrict it */
922 // if (record_status() == Recording) {
933 Session::set_auto_play (bool yn)
935 if (auto_play != yn) {
938 ControlChanged (AutoPlay);
943 Session::set_auto_return (bool yn)
945 if (auto_return != yn) {
948 ControlChanged (AutoReturn);
953 Session::set_crossfades_active (bool yn)
955 if (crossfades_active != yn) {
956 crossfades_active = yn;
958 ControlChanged (CrossFadesActive);
963 Session::set_do_not_record_plugins (bool yn)
965 if (do_not_record_plugins != yn) {
966 do_not_record_plugins = yn;
968 ControlChanged (RecordingPlugins);
973 Session::set_auto_input (bool yn)
975 if (auto_input != yn) {
978 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
979 /* auto-input only makes a difference if we're rolling */
981 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
983 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
984 if ((*i)->record_enabled ()) {
985 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
986 (*i)->monitor_input (!auto_input);
992 ControlChanged (AutoInput);
997 Session::reset_input_monitor_state ()
999 if (transport_rolling()) {
1001 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1003 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1004 if ((*i)->record_enabled ()) {
1005 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1006 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
1010 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1012 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1013 if ((*i)->record_enabled ()) {
1014 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1015 (*i)->monitor_input (Config->get_use_hardware_monitoring());
1023 Session::set_input_auto_connect (bool yn)
1026 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
1028 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1034 Session::get_input_auto_connect () const
1036 return (input_auto_connect & AutoConnectPhysical);
1040 Session::set_output_auto_connect (AutoConnectOption aco)
1042 output_auto_connect = aco;
1047 Session::auto_punch_start_changed (Location* location)
1049 replace_event (Event::PunchIn, location->start());
1051 if (get_record_enabled() && get_punch_in()) {
1052 /* capture start has been changed, so save new pending state */
1053 save_state ("", true);
1058 Session::auto_punch_end_changed (Location* location)
1060 jack_nframes_t when_to_stop = location->end();
1061 // when_to_stop += _worst_output_latency + _worst_input_latency;
1062 replace_event (Event::PunchOut, when_to_stop);
1066 Session::auto_punch_changed (Location* location)
1068 jack_nframes_t when_to_stop = location->end();
1070 replace_event (Event::PunchIn, location->start());
1071 //when_to_stop += _worst_output_latency + _worst_input_latency;
1072 replace_event (Event::PunchOut, when_to_stop);
1076 Session::auto_loop_changed (Location* location)
1078 replace_event (Event::AutoLoop, location->end(), location->start());
1080 if (transport_rolling() && get_auto_loop()) {
1082 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1084 if (_transport_frame > location->end()) {
1085 // relocate to beginning of loop
1086 clear_events (Event::LocateRoll);
1088 request_locate (location->start(), true);
1091 else if (seamless_loop && !loop_changing) {
1093 // schedule a locate-roll to refill the diskstreams at the
1094 // previous loop end
1095 loop_changing = true;
1097 if (location->end() > last_loopend) {
1098 clear_events (Event::LocateRoll);
1099 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1106 last_loopend = location->end();
1111 Session::set_auto_punch_location (Location* location)
1115 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1116 auto_punch_start_changed_connection.disconnect();
1117 auto_punch_end_changed_connection.disconnect();
1118 auto_punch_changed_connection.disconnect();
1119 existing->set_auto_punch (false, this);
1120 remove_event (existing->start(), Event::PunchIn);
1121 clear_events (Event::PunchOut);
1122 auto_punch_location_changed (0);
1127 if (location == 0) {
1131 if (location->end() <= location->start()) {
1132 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1136 auto_punch_start_changed_connection.disconnect();
1137 auto_punch_end_changed_connection.disconnect();
1138 auto_punch_changed_connection.disconnect();
1140 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1141 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1142 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1144 location->set_auto_punch (true, this);
1145 auto_punch_location_changed (location);
1149 Session::set_punch_in (bool yn)
1151 if (punch_in == yn) {
1157 if ((location = _locations.auto_punch_location()) != 0) {
1158 if ((punch_in = yn) == true) {
1159 replace_event (Event::PunchIn, location->start());
1161 remove_event (location->start(), Event::PunchIn);
1166 ControlChanged (PunchIn); /* EMIT SIGNAL */
1170 Session::set_punch_out (bool yn)
1172 if (punch_out == yn) {
1178 if ((location = _locations.auto_punch_location()) != 0) {
1179 if ((punch_out = yn) == true) {
1180 replace_event (Event::PunchOut, location->end());
1182 clear_events (Event::PunchOut);
1187 ControlChanged (PunchOut); /* EMIT SIGNAL */
1191 Session::set_auto_loop_location (Location* location)
1195 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1196 auto_loop_start_changed_connection.disconnect();
1197 auto_loop_end_changed_connection.disconnect();
1198 auto_loop_changed_connection.disconnect();
1199 existing->set_auto_loop (false, this);
1200 remove_event (existing->end(), Event::AutoLoop);
1201 auto_loop_location_changed (0);
1206 if (location == 0) {
1210 if (location->end() <= location->start()) {
1211 error << _("Session: you can't use a mark for auto loop") << endmsg;
1215 last_loopend = location->end();
1217 auto_loop_start_changed_connection.disconnect();
1218 auto_loop_end_changed_connection.disconnect();
1219 auto_loop_changed_connection.disconnect();
1221 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1222 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1223 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1225 location->set_auto_loop (true, this);
1226 auto_loop_location_changed (location);
1230 Session::locations_added (Location* ignored)
1236 Session::locations_changed ()
1238 _locations.apply (*this, &Session::handle_locations_changed);
1242 Session::handle_locations_changed (Locations::LocationList& locations)
1244 Locations::LocationList::iterator i;
1246 bool set_loop = false;
1247 bool set_punch = false;
1249 for (i = locations.begin(); i != locations.end(); ++i) {
1253 if (location->is_auto_punch()) {
1254 set_auto_punch_location (location);
1257 if (location->is_auto_loop()) {
1258 set_auto_loop_location (location);
1265 set_auto_loop_location (0);
1268 set_auto_punch_location (0);
1275 Session::enable_record ()
1277 /* XXX really atomic compare+swap here */
1278 if (g_atomic_int_get (&_record_status) != Recording) {
1279 g_atomic_int_set (&_record_status, Recording);
1280 _last_record_location = _transport_frame;
1281 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1283 if (Config->get_use_hardware_monitoring() && auto_input) {
1284 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1285 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1286 if ((*i)->record_enabled ()) {
1287 (*i)->monitor_input (true);
1292 RecordStateChanged ();
1297 Session::disable_record (bool rt_context, bool force)
1301 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1303 if (!Config->get_latched_record_enable () || force) {
1304 g_atomic_int_set (&_record_status, Disabled);
1306 if (rs == Recording) {
1307 g_atomic_int_set (&_record_status, Enabled);
1311 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1313 if (Config->get_use_hardware_monitoring() && auto_input) {
1314 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1316 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1317 if ((*i)->record_enabled ()) {
1318 (*i)->monitor_input (false);
1323 RecordStateChanged (); /* emit signal */
1326 remove_pending_capture_state ();
1332 Session::step_back_from_record ()
1334 g_atomic_int_set (&_record_status, Enabled);
1336 if (Config->get_use_hardware_monitoring()) {
1337 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1339 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1340 if (auto_input && (*i)->record_enabled ()) {
1341 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1342 (*i)->monitor_input (false);
1349 Session::maybe_enable_record ()
1351 g_atomic_int_set (&_record_status, Enabled);
1353 /* XXX this save should really happen in another thread. its needed so that
1354 pending capture state can be recovered if we crash.
1357 save_state ("", true);
1359 if (_transport_speed) {
1364 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1365 RecordStateChanged (); /* EMIT SIGNAL */
1372 Session::audible_frame () const
1375 jack_nframes_t offset;
1378 /* the first of these two possible settings for "offset"
1379 mean that the audible frame is stationary until
1380 audio emerges from the latency compensation
1383 the second means that the audible frame is stationary
1384 until audio would emerge from a physical port
1385 in the absence of any plugin latency compensation
1388 offset = _worst_output_latency;
1390 if (offset > current_block_size) {
1391 offset -= current_block_size;
1393 /* XXX is this correct? if we have no external
1394 physical connections and everything is internal
1395 then surely this is zero? still, how
1396 likely is that anyway?
1398 offset = current_block_size;
1401 if (synced_to_jack()) {
1402 tf = _engine.transport_frame();
1404 tf = _transport_frame;
1407 if (_transport_speed == 0) {
1417 if (!non_realtime_work_pending()) {
1421 /* take latency into account */
1430 Session::set_frame_rate (jack_nframes_t frames_per_second)
1432 /** \fn void Session::set_frame_size(jack_nframes_t)
1433 the AudioEngine object that calls this guarantees
1434 that it will not be called while we are also in
1435 ::process(). Its fine to do things that block
1439 _base_frame_rate = frames_per_second;
1443 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1445 // XXX we need some equivalent to this, somehow
1446 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1450 /* XXX need to reset/reinstantiate all LADSPA plugins */
1454 Session::set_block_size (jack_nframes_t nframes)
1456 /* the AudioEngine guarantees
1457 that it will not be called while we are also in
1458 ::process(). It is therefore fine to do things that block
1463 vector<Sample*>::iterator i;
1466 current_block_size = nframes;
1468 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1472 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1476 _passthru_buffers.clear ();
1477 _silent_buffers.clear ();
1479 ensure_passthru_buffers (np);
1481 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1485 #ifdef NO_POSIX_MEMALIGN
1486 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1488 posix_memalign((void **)&buf,16,current_block_size * 4);
1492 memset (*i, 0, sizeof (Sample) * current_block_size);
1496 if (_gain_automation_buffer) {
1497 delete [] _gain_automation_buffer;
1499 _gain_automation_buffer = new gain_t[nframes];
1501 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1503 boost::shared_ptr<RouteList> r = routes.reader ();
1505 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1506 (*i)->set_block_size (nframes);
1509 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1510 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1511 (*i)->set_block_size (nframes);
1514 set_worst_io_latencies ();
1519 Session::set_default_fade (float steepness, float fade_msecs)
1522 jack_nframes_t fade_frames;
1524 /* Don't allow fade of less 1 frame */
1526 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1533 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1537 default_fade_msecs = fade_msecs;
1538 default_fade_steepness = steepness;
1541 // jlc, WTF is this!
1542 Glib::RWLock::ReaderLock lm (route_lock);
1543 AudioRegion::set_default_fade (steepness, fade_frames);
1548 /* XXX have to do this at some point */
1549 /* foreach region using default fade, reset, then
1550 refill_all_diskstream_buffers ();
1555 struct RouteSorter {
1556 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1557 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1559 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1562 if (r1->fed_by.empty()) {
1563 if (r2->fed_by.empty()) {
1564 /* no ardour-based connections inbound to either route. just use signal order */
1565 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1567 /* r2 has connections, r1 does not; run r1 early */
1571 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1578 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1580 shared_ptr<Route> r2;
1582 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1583 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1587 /* make a copy of the existing list of routes that feed r1 */
1589 set<shared_ptr<Route> > existing = r1->fed_by;
1591 /* for each route that feeds r1, recurse, marking it as feeding
1595 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1598 /* r2 is a route that feeds r1 which somehow feeds base. mark
1599 base as being fed by r2
1602 rbase->fed_by.insert (r2);
1606 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1610 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1614 /* now recurse, so that we can mark base as being fed by
1615 all routes that feed r2
1618 trace_terminal (r2, rbase);
1625 Session::resort_routes ()
1627 /* don't do anything here with signals emitted
1628 by Routes while we are being destroyed.
1631 if (_state_of_the_state & Deletion) {
1638 RCUWriter<RouteList> writer (routes);
1639 shared_ptr<RouteList> r = writer.get_copy ();
1640 resort_routes_using (r);
1641 /* writer goes out of scope and forces update */
1646 Session::resort_routes_using (shared_ptr<RouteList> r)
1648 RouteList::iterator i, j;
1650 for (i = r->begin(); i != r->end(); ++i) {
1652 (*i)->fed_by.clear ();
1654 for (j = r->begin(); j != r->end(); ++j) {
1656 /* although routes can feed themselves, it will
1657 cause an endless recursive descent if we
1658 detect it. so don't bother checking for
1666 if ((*j)->feeds (*i)) {
1667 (*i)->fed_by.insert (*j);
1672 for (i = r->begin(); i != r->end(); ++i) {
1673 trace_terminal (*i, *i);
1680 cerr << "finished route resort\n";
1682 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1683 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1690 list<boost::shared_ptr<AudioTrack> >
1691 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1693 char track_name[32];
1694 uint32_t track_id = 0;
1696 uint32_t channels_used = 0;
1698 RouteList new_routes;
1699 list<boost::shared_ptr<AudioTrack> > ret;
1701 /* count existing audio tracks */
1704 shared_ptr<RouteList> r = routes.reader ();
1706 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1707 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1708 if (!(*i)->hidden()) {
1710 channels_used += (*i)->n_inputs();
1716 vector<string> physinputs;
1717 vector<string> physoutputs;
1718 uint32_t nphysical_in;
1719 uint32_t nphysical_out;
1721 _engine.get_physical_outputs (physoutputs);
1722 _engine.get_physical_inputs (physinputs);
1726 /* check for duplicate route names, since we might have pre-existing
1727 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1728 save, close,restart,add new route - first named route is now
1736 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1738 if (route_by_name (track_name) == 0) {
1742 } while (track_id < (UINT_MAX-1));
1744 if (input_auto_connect & AutoConnectPhysical) {
1745 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1750 if (output_auto_connect & AutoConnectPhysical) {
1751 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1757 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1759 if (track->ensure_io (input_channels, output_channels, false, this)) {
1760 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1761 input_channels, output_channels)
1766 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1770 if (input_auto_connect & AutoConnectPhysical) {
1771 port = physinputs[(channels_used+x)%nphysical_in];
1774 if (port.length() && track->connect_input (track->input (x), port, this)) {
1780 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1784 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1785 port = physoutputs[(channels_used+x)%nphysical_out];
1786 } else if (output_auto_connect & AutoConnectMaster) {
1788 port = _master_out->input (x%_master_out->n_inputs())->name();
1792 if (port.length() && track->connect_output (track->output (x), port, this)) {
1797 channels_used += track->n_inputs ();
1800 vector<string> cports;
1801 uint32_t ni = _control_out->n_inputs();
1803 for (n = 0; n < ni; ++n) {
1804 cports.push_back (_control_out->input(n)->name());
1807 track->set_control_outs (cports);
1810 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1811 track->set_remote_control_id (ntracks());
1813 new_routes.push_back (track);
1814 ret.push_back (track);
1817 catch (failed_constructor &err) {
1818 error << _("Session: could not create new audio track.") << endmsg;
1819 // XXX should we delete the tracks already created?
1827 if (!new_routes.empty()) {
1828 add_routes (new_routes, false);
1829 save_state (_current_snapshot_name);
1836 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1839 uint32_t bus_id = 1;
1844 /* count existing audio busses */
1847 shared_ptr<RouteList> r = routes.reader ();
1849 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1850 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1851 if (!(*i)->hidden()) {
1858 vector<string> physinputs;
1859 vector<string> physoutputs;
1861 _engine.get_physical_outputs (physoutputs);
1862 _engine.get_physical_inputs (physinputs);
1869 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1871 if (route_by_name (bus_name) == 0) {
1875 } while (bus_id < (UINT_MAX-1));
1878 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1880 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1881 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1882 input_channels, output_channels)
1886 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1890 if (input_auto_connect & AutoConnectPhysical) {
1891 port = physinputs[((n+x)%n_physical_inputs)];
1894 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1899 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1903 if (output_auto_connect & AutoConnectPhysical) {
1904 port = physoutputs[((n+x)%n_physical_outputs)];
1905 } else if (output_auto_connect & AutoConnectMaster) {
1907 port = _master_out->input (x%_master_out->n_inputs())->name();
1911 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1917 vector<string> cports;
1918 uint32_t ni = _control_out->n_inputs();
1920 for (uint32_t n = 0; n < ni; ++n) {
1921 cports.push_back (_control_out->input(n)->name());
1923 bus->set_control_outs (cports);
1926 ret.push_back (bus);
1930 catch (failed_constructor &err) {
1931 error << _("Session: could not create new audio route.") << endmsg;
1940 add_routes (ret, false);
1941 save_state (_current_snapshot_name);
1949 Session::add_routes (RouteList& new_routes, bool save)
1952 RCUWriter<RouteList> writer (routes);
1953 shared_ptr<RouteList> r = writer.get_copy ();
1954 r->insert (r->end(), new_routes.begin(), new_routes.end());
1955 resort_routes_using (r);
1958 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1959 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), (*x)));
1960 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1961 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1962 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1964 if ((*x)->master()) {
1968 if ((*x)->control()) {
1969 _control_out = (*x);
1976 save_state (_current_snapshot_name);
1979 RouteAdded (new_routes); /* EMIT SIGNAL */
1983 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1985 /* need to do this in case we're rolling at the time, to prevent false underruns */
1986 dstream->do_refill_with_alloc();
1989 RCUWriter<DiskstreamList> writer (diskstreams);
1990 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1991 ds->push_back (dstream);
1994 dstream->set_block_size (current_block_size);
1996 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1997 /* this will connect to future changes, and check the current length */
1998 diskstream_playlist_changed (dstream);
2000 dstream->prepare ();
2004 Session::remove_route (shared_ptr<Route> route)
2007 RCUWriter<RouteList> writer (routes);
2008 shared_ptr<RouteList> rs = writer.get_copy ();
2011 /* deleting the master out seems like a dumb
2012 idea, but its more of a UI policy issue
2016 if (route == _master_out) {
2017 _master_out = shared_ptr<Route> ((Route*) 0);
2020 if (route == _control_out) {
2021 _control_out = shared_ptr<Route> ((Route*) 0);
2023 /* cancel control outs for all routes */
2025 vector<string> empty;
2027 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2028 (*r)->set_control_outs (empty);
2032 update_route_solo_state ();
2034 /* writer goes out of scope, forces route list update */
2037 // FIXME: audio specific
2039 boost::shared_ptr<AudioDiskstream> ds;
2041 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2042 ds = at->audio_diskstream();
2048 RCUWriter<DiskstreamList> dsl (diskstreams);
2049 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2054 find_current_end ();
2056 update_latency_compensation (false, false);
2059 /* XXX should we disconnect from the Route's signals ? */
2061 save_state (_current_snapshot_name);
2063 /* try to cause everyone to drop their references */
2065 route->drop_references ();
2069 Session::route_mute_changed (void* src)
2075 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2077 if (solo_update_disabled) {
2084 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2086 shared_ptr<RouteList> r = routes.reader ();
2088 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2090 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2094 /* don't mess with busses */
2096 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2102 /* don't mess with tracks */
2104 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2109 if ((*i) != route &&
2110 ((*i)->mix_group () == 0 ||
2111 (*i)->mix_group () != route->mix_group () ||
2112 !route->mix_group ()->is_active())) {
2114 if ((*i)->soloed()) {
2116 /* if its already soloed, and solo latching is enabled,
2117 then leave it as it is.
2120 if (_solo_latched) {
2127 solo_update_disabled = true;
2128 (*i)->set_solo (false, src);
2129 solo_update_disabled = false;
2133 bool something_soloed = false;
2134 bool same_thing_soloed = false;
2135 bool signal = false;
2137 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2138 if ((*i)->soloed()) {
2139 something_soloed = true;
2140 if (dynamic_cast<AudioTrack*>((*i).get())) {
2142 same_thing_soloed = true;
2147 same_thing_soloed = true;
2155 if (something_soloed != currently_soloing) {
2157 currently_soloing = something_soloed;
2160 modify_solo_mute (is_track, same_thing_soloed);
2163 SoloActive (currently_soloing);
2170 Session::set_solo_latched (bool yn)
2172 if (yn != _solo_latched) {
2175 ControlChanged (SoloLatch);
2180 Session::update_route_solo_state ()
2183 bool is_track = false;
2184 bool signal = false;
2186 /* caller must hold RouteLock */
2188 /* this is where we actually implement solo by changing
2189 the solo mute setting of each track.
2192 shared_ptr<RouteList> r = routes.reader ();
2194 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2195 if ((*i)->soloed()) {
2197 if (dynamic_cast<AudioTrack*>((*i).get())) {
2204 if (mute != currently_soloing) {
2206 currently_soloing = mute;
2209 if (!is_track && !mute) {
2211 /* nothing is soloed */
2213 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2214 (*i)->set_solo_mute (false);
2224 modify_solo_mute (is_track, mute);
2227 SoloActive (currently_soloing);
2232 Session::modify_solo_mute (bool is_track, bool mute)
2234 shared_ptr<RouteList> r = routes.reader ();
2236 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2240 /* only alter track solo mute */
2242 if (dynamic_cast<AudioTrack*>((*i).get())) {
2243 if ((*i)->soloed()) {
2244 (*i)->set_solo_mute (!mute);
2246 (*i)->set_solo_mute (mute);
2252 /* only alter bus solo mute */
2254 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2256 if ((*i)->soloed()) {
2258 (*i)->set_solo_mute (false);
2262 /* don't mute master or control outs
2263 in response to another bus solo
2266 if ((*i) != _master_out &&
2267 (*i) != _control_out) {
2268 (*i)->set_solo_mute (mute);
2279 Session::catch_up_on_solo ()
2281 /* this is called after set_state() to catch the full solo
2282 state, which can't be correctly determined on a per-route
2283 basis, but needs the global overview that only the session
2286 update_route_solo_state();
2290 Session::route_by_name (string name)
2292 shared_ptr<RouteList> r = routes.reader ();
2294 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2295 if ((*i)->name() == name) {
2300 return shared_ptr<Route> ((Route*) 0);
2304 Session::route_by_id (PBD::ID id)
2306 shared_ptr<RouteList> r = routes.reader ();
2308 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2309 if ((*i)->id() == id) {
2314 return shared_ptr<Route> ((Route*) 0);
2318 Session::route_by_remote_id (uint32_t id)
2320 shared_ptr<RouteList> r = routes.reader ();
2322 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2323 if ((*i)->remote_control_id() == id) {
2328 return shared_ptr<Route> ((Route*) 0);
2332 Session::find_current_end ()
2334 if (_state_of_the_state & Loading) {
2338 jack_nframes_t max = get_maximum_extent ();
2340 if (max > end_location->end()) {
2341 end_location->set_end (max);
2343 DurationChanged(); /* EMIT SIGNAL */
2348 Session::get_maximum_extent () const
2350 jack_nframes_t max = 0;
2353 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2355 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2356 Playlist* pl = (*i)->playlist();
2357 if ((me = pl->get_maximum_extent()) > max) {
2365 boost::shared_ptr<Diskstream>
2366 Session::diskstream_by_name (string name)
2368 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2370 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2371 if ((*i)->name() == name) {
2376 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2379 boost::shared_ptr<Diskstream>
2380 Session::diskstream_by_id (const PBD::ID& id)
2382 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2384 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2385 if ((*i)->id() == id) {
2390 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2393 /* AudioRegion management */
2396 Session::new_region_name (string old)
2398 string::size_type last_period;
2400 string::size_type len = old.length() + 64;
2403 if ((last_period = old.find_last_of ('.')) == string::npos) {
2405 /* no period present - add one explicitly */
2408 last_period = old.length() - 1;
2413 number = atoi (old.substr (last_period+1).c_str());
2417 while (number < (UINT_MAX-1)) {
2419 AudioRegionList::const_iterator i;
2424 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2427 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2428 if (i->second->name() == sbuf) {
2433 if (i == audio_regions.end()) {
2438 if (number != (UINT_MAX-1)) {
2442 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2447 Session::region_name (string& result, string base, bool newlevel) const
2454 Glib::Mutex::Lock lm (region_lock);
2456 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2464 /* XXX this is going to be slow. optimize me later */
2469 string::size_type pos;
2471 pos = base.find_last_of ('.');
2473 /* pos may be npos, but then we just use entire base */
2475 subbase = base.substr (0, pos);
2479 bool name_taken = true;
2482 Glib::Mutex::Lock lm (region_lock);
2484 for (int n = 1; n < 5000; ++n) {
2487 snprintf (buf, sizeof (buf), ".%d", n);
2492 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2493 if (i->second->name() == result) {
2506 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2514 Session::add_region (boost::shared_ptr<Region> region)
2516 boost::shared_ptr<AudioRegion> ar;
2517 boost::shared_ptr<AudioRegion> oar;
2521 Glib::Mutex::Lock lm (region_lock);
2523 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2525 AudioRegionList::iterator x;
2527 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2529 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2531 if (ar->region_list_equivalent (oar)) {
2536 if (x == audio_regions.end()) {
2538 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2540 entry.first = region->id();
2543 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2555 fatal << _("programming error: ")
2556 << X_("unknown region type passed to Session::add_region()")
2563 /* mark dirty because something has changed even if we didn't
2564 add the region to the region list.
2570 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
2571 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2572 AudioRegionAdded (ar); /* EMIT SIGNAL */
2577 Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
2579 if (what_changed & Region::HiddenChanged) {
2580 /* relay hidden changes */
2581 RegionHiddenChange (region);
2586 Session::region_renamed (boost::shared_ptr<Region> region)
2588 add_region (region);
2592 Session::remove_region (boost::shared_ptr<Region> region)
2594 AudioRegionList::iterator i;
2595 boost::shared_ptr<AudioRegion> ar;
2596 bool removed = false;
2599 Glib::Mutex::Lock lm (region_lock);
2601 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2602 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2603 audio_regions.erase (i);
2609 fatal << _("programming error: ")
2610 << X_("unknown region type passed to Session::remove_region()")
2616 /* mark dirty because something has changed even if we didn't
2617 remove the region from the region list.
2623 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2627 boost::shared_ptr<AudioRegion>
2628 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2630 AudioRegionList::iterator i;
2631 boost::shared_ptr<AudioRegion> region;
2632 Glib::Mutex::Lock lm (region_lock);
2634 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2638 if (region->whole_file()) {
2640 if (child->source_equivalent (region)) {
2646 return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
2650 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2652 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2653 (*i)->get_region_list_equivalent_regions (region, result);
2657 Session::destroy_region (boost::shared_ptr<Region> region)
2659 boost::shared_ptr<AudioRegion> aregion;
2661 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2665 if (aregion->playlist()) {
2666 aregion->playlist()->destroy_region (region);
2669 vector<boost::shared_ptr<Source> > srcs;
2671 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2672 srcs.push_back (aregion->source (n));
2675 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2677 if ((*i).use_count() == 1) {
2678 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2681 (afs)->mark_for_remove ();
2684 (*i)->drop_references ();
2692 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2694 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2695 destroy_region (*i);
2701 Session::remove_last_capture ()
2703 list<boost::shared_ptr<Region> > r;
2705 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2707 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2708 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2711 r.insert (r.end(), l.begin(), l.end());
2716 destroy_regions (r);
2721 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2727 /* Source Management */
2730 Session::add_source (boost::shared_ptr<Source> source)
2732 boost::shared_ptr<AudioFileSource> afs;
2734 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2736 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2737 pair<AudioSourceList::iterator,bool> result;
2739 entry.first = source->id();
2743 Glib::Mutex::Lock lm (audio_source_lock);
2744 result = audio_sources.insert (entry);
2747 if (!result.second) {
2748 cerr << "\tNOT inserted ? " << result.second << endl;
2751 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2754 SourceAdded (source); /* EMIT SIGNAL */
2756 cerr << "\tNOT AUDIO FILE\n";
2761 Session::remove_source (boost::weak_ptr<Source> src)
2763 AudioSourceList::iterator i;
2764 boost::shared_ptr<Source> source = src.lock();
2767 cerr << "removing a source DEAD\n";
2769 cerr << "removing a source " << source->name () << endl;
2772 Glib::Mutex::Lock lm (audio_source_lock);
2774 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2775 audio_sources.erase (i);
2779 if (!_state_of_the_state & InCleanup) {
2781 /* save state so we don't end up with a session file
2782 referring to non-existent sources.
2785 save_state (_current_snapshot_name);
2788 SourceRemoved(source); /* EMIT SIGNAL */
2792 boost::shared_ptr<Source>
2793 Session::source_by_id (const PBD::ID& id)
2795 Glib::Mutex::Lock lm (audio_source_lock);
2796 AudioSourceList::iterator i;
2797 boost::shared_ptr<Source> source;
2799 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2803 /* XXX search MIDI or other searches here */
2809 Session::peak_path_from_audio_path (string audio_path) const
2814 res += PBD::basename_nosuffix (audio_path);
2821 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2824 string old_basename = PBD::basename_nosuffix (oldname);
2825 string new_legalized = legalize_for_path (newname);
2827 /* note: we know (or assume) the old path is already valid */
2831 /* destructive file sources have a name of the form:
2833 /path/to/Tnnnn-NAME(%[LR])?.wav
2835 the task here is to replace NAME with the new name.
2838 /* find last slash */
2842 string::size_type slash;
2843 string::size_type dash;
2845 if ((slash = path.find_last_of ('/')) == string::npos) {
2849 dir = path.substr (0, slash+1);
2851 /* '-' is not a legal character for the NAME part of the path */
2853 if ((dash = path.find_last_of ('-')) == string::npos) {
2857 prefix = path.substr (slash+1, dash-(slash+1));
2862 path += new_legalized;
2863 path += ".wav"; /* XXX gag me with a spoon */
2867 /* non-destructive file sources have a name of the form:
2869 /path/to/NAME-nnnnn(%[LR])?.wav
2871 the task here is to replace NAME with the new name.
2876 string::size_type slash;
2877 string::size_type dash;
2878 string::size_type postfix;
2880 /* find last slash */
2882 if ((slash = path.find_last_of ('/')) == string::npos) {
2886 dir = path.substr (0, slash+1);
2888 /* '-' is not a legal character for the NAME part of the path */
2890 if ((dash = path.find_last_of ('-')) == string::npos) {
2894 suffix = path.substr (dash+1);
2896 // Suffix is now everything after the dash. Now we need to eliminate
2897 // the nnnnn part, which is done by either finding a '%' or a '.'
2899 postfix = suffix.find_last_of ("%");
2900 if (postfix == string::npos) {
2901 postfix = suffix.find_last_of ('.');
2904 if (postfix != string::npos) {
2905 suffix = suffix.substr (postfix);
2907 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2911 const uint32_t limit = 10000;
2912 char buf[PATH_MAX+1];
2914 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2916 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2918 if (access (buf, F_OK) != 0) {
2926 error << "FATAL ERROR! Could not find a " << endl;
2935 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2939 char buf[PATH_MAX+1];
2940 const uint32_t limit = 10000;
2944 legalized = legalize_for_path (name);
2946 /* find a "version" of the file name that doesn't exist in
2947 any of the possible directories.
2950 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2952 vector<space_and_path>::iterator i;
2953 uint32_t existing = 0;
2955 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2959 spath += sound_dir (false);
2963 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2964 } else if (nchan == 2) {
2966 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2968 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2970 } else if (nchan < 26) {
2971 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2973 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2981 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2982 } else if (nchan == 2) {
2984 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2986 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2988 } else if (nchan < 26) {
2989 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2991 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2995 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3001 if (existing == 0) {
3006 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3007 throw failed_constructor();
3011 /* we now have a unique name for the file, but figure out where to
3017 spath = discover_best_sound_dir ();
3019 string::size_type pos = foo.find_last_of ('/');
3021 if (pos == string::npos) {
3024 spath += foo.substr (pos + 1);
3030 boost::shared_ptr<AudioFileSource>
3031 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3033 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3034 return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, spath, destructive, frame_rate()));
3037 /* Playlist management */
3040 Session::playlist_by_name (string name)
3042 Glib::Mutex::Lock lm (playlist_lock);
3043 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3044 if ((*i)->name() == name) {
3048 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3049 if ((*i)->name() == name) {
3057 Session::add_playlist (Playlist* playlist)
3059 if (playlist->hidden()) {
3064 Glib::Mutex::Lock lm (playlist_lock);
3065 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3066 playlists.insert (playlists.begin(), playlist);
3068 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3069 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
3075 PlaylistAdded (playlist); /* EMIT SIGNAL */
3079 Session::track_playlist (Playlist* pl, bool inuse)
3081 PlaylistList::iterator x;
3084 Glib::Mutex::Lock lm (playlist_lock);
3087 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3089 unused_playlists.insert (pl);
3091 if ((x = playlists.find (pl)) != playlists.end()) {
3092 playlists.erase (x);
3097 //cerr << "shifting playlist to used: " << pl->name() << endl;
3099 playlists.insert (pl);
3101 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3102 unused_playlists.erase (x);
3109 Session::remove_playlist (Playlist* playlist)
3111 if (_state_of_the_state & Deletion) {
3116 Glib::Mutex::Lock lm (playlist_lock);
3117 // cerr << "removing playlist: " << playlist->name() << endl;
3119 PlaylistList::iterator i;
3121 i = find (playlists.begin(), playlists.end(), playlist);
3123 if (i != playlists.end()) {
3124 playlists.erase (i);
3127 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3128 if (i != unused_playlists.end()) {
3129 unused_playlists.erase (i);
3136 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3140 Session::set_audition (boost::shared_ptr<Region> r)
3142 pending_audition_region = r;
3143 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3144 schedule_butler_transport_work ();
3148 Session::audition_playlist ()
3150 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3151 ev->region.reset ();
3156 Session::non_realtime_set_audition ()
3158 if (!pending_audition_region) {
3159 auditioner->audition_current_playlist ();
3161 auditioner->audition_region (pending_audition_region);
3162 pending_audition_region.reset ();
3164 AuditionActive (true); /* EMIT SIGNAL */
3168 Session::audition_region (boost::shared_ptr<Region> r)
3170 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3176 Session::cancel_audition ()
3178 if (auditioner->active()) {
3179 auditioner->cancel_audition ();
3180 AuditionActive (false); /* EMIT SIGNAL */
3185 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3187 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3191 Session::remove_empty_sounds ()
3193 PathScanner scanner;
3195 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3197 Glib::Mutex::Lock lm (audio_source_lock);
3199 regex_t compiled_tape_track_pattern;
3202 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3206 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3208 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3212 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3214 /* never remove files that appear to be a tape track */
3216 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3221 if (AudioFileSource::is_empty (*this, *(*i))) {
3223 unlink ((*i)->c_str());
3225 string peak_path = peak_path_from_audio_path (**i);
3226 unlink (peak_path.c_str());
3232 delete possible_audiofiles;
3236 Session::is_auditioning () const
3238 /* can be called before we have an auditioner object */
3240 return auditioner->active();
3247 Session::set_all_solo (bool yn)
3249 shared_ptr<RouteList> r = routes.reader ();
3251 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3252 if (!(*i)->hidden()) {
3253 (*i)->set_solo (yn, this);
3261 Session::set_all_mute (bool yn)
3263 shared_ptr<RouteList> r = routes.reader ();
3265 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3266 if (!(*i)->hidden()) {
3267 (*i)->set_mute (yn, this);
3275 Session::n_diskstreams () const
3279 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3281 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3282 if (!(*i)->hidden()) {
3290 Session::graph_reordered ()
3292 /* don't do this stuff if we are setting up connections
3293 from a set_state() call.
3296 if (_state_of_the_state & InitialConnecting) {
3302 /* force all diskstreams to update their capture offset values to
3303 reflect any changes in latencies within the graph.
3306 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3308 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3309 (*i)->set_capture_offset ();
3314 Session::record_disenable_all ()
3316 record_enable_change_all (false);
3320 Session::record_enable_all ()
3322 record_enable_change_all (true);
3326 Session::record_enable_change_all (bool yn)
3328 shared_ptr<RouteList> r = routes.reader ();
3330 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3333 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3334 at->set_record_enable (yn, this);
3338 /* since we don't keep rec-enable state, don't mark session dirty */
3342 Session::add_redirect (Redirect* redirect)
3346 PortInsert* port_insert;
3347 PluginInsert* plugin_insert;
3349 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3350 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3351 _port_inserts.insert (_port_inserts.begin(), port_insert);
3352 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3353 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3355 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3358 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3359 _sends.insert (_sends.begin(), send);
3361 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3365 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3371 Session::remove_redirect (Redirect* redirect)
3375 PortInsert* port_insert;
3376 PluginInsert* plugin_insert;
3378 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3379 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3380 _port_inserts.remove (port_insert);
3381 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3382 _plugin_inserts.remove (plugin_insert);
3384 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3387 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3388 _sends.remove (send);
3390 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3398 Session::available_capture_duration ()
3400 const double scale = 4096.0 / sizeof (Sample);
3402 if (_total_free_4k_blocks * scale > (double) max_frames) {
3406 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3410 Session::add_connection (ARDOUR::Connection* connection)
3413 Glib::Mutex::Lock guard (connection_lock);
3414 _connections.push_back (connection);
3417 ConnectionAdded (connection); /* EMIT SIGNAL */
3423 Session::remove_connection (ARDOUR::Connection* connection)
3425 bool removed = false;
3428 Glib::Mutex::Lock guard (connection_lock);
3429 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3431 if (i != _connections.end()) {
3432 _connections.erase (i);
3438 ConnectionRemoved (connection); /* EMIT SIGNAL */
3444 ARDOUR::Connection *
3445 Session::connection_by_name (string name) const
3447 Glib::Mutex::Lock lm (connection_lock);
3449 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3450 if ((*i)->name() == name) {
3459 Session::set_edit_mode (EditMode mode)
3464 Glib::Mutex::Lock lm (playlist_lock);
3466 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3467 (*i)->set_edit_mode (mode);
3472 ControlChanged (EditingMode); /* EMIT SIGNAL */
3476 Session::tempo_map_changed (Change ignored)
3483 Session::ensure_passthru_buffers (uint32_t howmany)
3485 while (howmany > _passthru_buffers.size()) {
3487 #ifdef NO_POSIX_MEMALIGN
3488 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3490 posix_memalign((void **)&p,16,current_block_size * 4);
3492 _passthru_buffers.push_back (p);
3496 #ifdef NO_POSIX_MEMALIGN
3497 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3499 posix_memalign((void **)&p,16,current_block_size * 4);
3501 memset (p, 0, sizeof (Sample) * current_block_size);
3502 _silent_buffers.push_back (p);
3506 #ifdef NO_POSIX_MEMALIGN
3507 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3509 posix_memalign((void **)&p,16,current_block_size * 4);
3511 memset (p, 0, sizeof (Sample) * current_block_size);
3512 _send_buffers.push_back (p);
3515 allocate_pan_automation_buffers (current_block_size, howmany, false);
3519 Session::next_send_name ()
3522 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3527 Session::next_insert_name ()
3530 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3534 /* Named Selection management */
3537 Session::named_selection_by_name (string name)
3539 Glib::Mutex::Lock lm (named_selection_lock);
3540 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3541 if ((*i)->name == name) {
3549 Session::add_named_selection (NamedSelection* named_selection)
3552 Glib::Mutex::Lock lm (named_selection_lock);
3553 named_selections.insert (named_selections.begin(), named_selection);
3558 NamedSelectionAdded (); /* EMIT SIGNAL */
3562 Session::remove_named_selection (NamedSelection* named_selection)
3564 bool removed = false;
3567 Glib::Mutex::Lock lm (named_selection_lock);
3569 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3571 if (i != named_selections.end()) {
3573 named_selections.erase (i);
3580 NamedSelectionRemoved (); /* EMIT SIGNAL */
3585 Session::reset_native_file_format ()
3587 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3589 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3590 (*i)->reset_write_sources (false);
3595 Session::route_name_unique (string n) const
3597 shared_ptr<RouteList> r = routes.reader ();
3599 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3600 if ((*i)->name() == n) {
3609 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3611 return fs->move_to_trash (dead_sound_dir_name);
3615 Session::n_playlists () const
3617 Glib::Mutex::Lock lm (playlist_lock);
3618 return playlists.size();
3622 Session::set_solo_model (SoloModel sm)
3624 if (sm != _solo_model) {
3626 ControlChanged (SoloingModel);
3632 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3634 if (!force && howmany <= _npan_buffers) {
3638 if (_pan_automation_buffer) {
3640 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3641 delete [] _pan_automation_buffer[i];
3644 delete [] _pan_automation_buffer;
3647 _pan_automation_buffer = new pan_t*[howmany];
3649 for (uint32_t i = 0; i < howmany; ++i) {
3650 _pan_automation_buffer[i] = new pan_t[nframes];
3653 _npan_buffers = howmany;
3657 Session::freeze (InterThreadInfo& itt)
3659 shared_ptr<RouteList> r = routes.reader ();
3661 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3665 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3666 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3677 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3678 bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
3682 boost::shared_ptr<AudioFileSource> fsource;
3684 char buf[PATH_MAX+1];
3687 jack_nframes_t position;
3688 jack_nframes_t this_chunk;
3689 jack_nframes_t to_do;
3690 vector<Sample*> buffers;
3692 // any bigger than this seems to cause stack overflows in called functions
3693 const jack_nframes_t chunk_size = (128 * 1024)/4;
3695 g_atomic_int_set (&processing_prohibited, 1);
3697 /* call tree *MUST* hold route_lock */
3699 if ((playlist = track.diskstream()->playlist()) == 0) {
3703 /* external redirects will be a problem */
3705 if (track.has_external_redirects()) {
3709 nchans = track.audio_diskstream()->n_channels();
3711 dir = discover_best_sound_dir ();
3713 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3715 for (x = 0; x < 99999; ++x) {
3716 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3717 if (access (buf, F_OK) != 0) {
3723 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3728 fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (*this, buf, false, frame_rate()));
3731 catch (failed_constructor& err) {
3732 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3736 srcs.push_back (fsource);
3739 /* XXX need to flush all redirects */
3744 /* create a set of reasonably-sized buffers */
3746 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3748 #ifdef NO_POSIX_MEMALIGN
3749 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3751 posix_memalign((void **)&b,16,chunk_size * 4);
3753 buffers.push_back (b);
3756 while (to_do && !itt.cancel) {
3758 this_chunk = min (to_do, chunk_size);
3760 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3765 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3766 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3769 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3775 start += this_chunk;
3776 to_do -= this_chunk;
3778 itt.progress = (float) (1.0 - ((double) to_do / len));
3787 xnow = localtime (&now);
3789 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3790 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3793 afs->update_header (position, *xnow, now);
3797 /* build peakfile for new source */
3799 for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3800 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3802 afs->build_peaks ();
3811 for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3812 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3815 afs->mark_for_remove ();
3818 (*src)->drop_references ();
3822 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3826 g_atomic_int_set (&processing_prohibited, 0);
3834 Session::get_silent_buffers (uint32_t howmany)
3836 for (uint32_t i = 0; i < howmany; ++i) {
3837 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3839 return _silent_buffers;
3843 Session::ntracks () const
3846 shared_ptr<RouteList> r = routes.reader ();
3848 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3849 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3858 Session::nbusses () const
3861 shared_ptr<RouteList> r = routes.reader ();
3863 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3864 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3873 Session::set_layer_model (LayerModel lm)
3875 if (lm != layer_model) {
3878 ControlChanged (LayeringModel);
3883 Session::set_xfade_model (CrossfadeModel xm)
3885 if (xm != xfade_model) {
3888 ControlChanged (CrossfadingModel);
3893 Session::handle_configuration_change (const char* parameter)
3895 if (!strcmp (parameter, "use-video-sync")) {
3896 if (_transport_speed == 0.0f) {
3897 waiting_for_sync_offset = true;
3903 Session::add_curve(Curve *curve)
3905 curves[curve->id()] = curve;
3909 Session::add_automation_list(AutomationList *al)
3911 automation_lists[al->id()] = al;