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/utils.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/midi_diskstream.h>
53 #include <ardour/midi_playlist.h>
54 #include <ardour/midi_region.h>
55 #include <ardour/smf_source.h>
56 #include <ardour/destructive_filesource.h>
57 #include <ardour/auditioner.h>
58 #include <ardour/recent_sessions.h>
59 #include <ardour/redirect.h>
60 #include <ardour/send.h>
61 #include <ardour/insert.h>
62 #include <ardour/connection.h>
63 #include <ardour/slave.h>
64 #include <ardour/tempo.h>
65 #include <ardour/audio_track.h>
66 #include <ardour/midi_track.h>
67 #include <ardour/cycle_timer.h>
68 #include <ardour/named_selection.h>
69 #include <ardour/crossfade.h>
70 #include <ardour/playlist.h>
71 #include <ardour/click.h>
74 #include <ardour/osc.h>
80 using namespace ARDOUR;
83 const char* Session::_template_suffix = X_(".template");
84 const char* Session::_statefile_suffix = X_(".ardour");
85 const char* Session::_pending_suffix = X_(".pending");
86 const char* Session::sound_dir_name = X_("sounds");
87 const char* Session::tape_dir_name = X_("tapes");
88 const char* Session::peak_dir_name = X_("peaks");
89 const char* Session::dead_sound_dir_name = X_("dead_sounds");
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::SMPTEOffsetChanged;
98 sigc::signal<void> Session::SendFeedback;
102 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
105 char buf[PATH_MAX+1];
109 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
110 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
116 /* check to see if it exists, and what it is */
118 if (stat (str.c_str(), &statbuf)) {
119 if (errno == ENOENT) {
122 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
130 /* it exists, so it must either be the name
131 of the directory, or the name of the statefile
135 if (S_ISDIR (statbuf.st_mode)) {
137 string::size_type slash = str.find_last_of ('/');
139 if (slash == string::npos) {
141 /* a subdirectory of cwd, so statefile should be ... */
147 tmp += _statefile_suffix;
151 if (stat (tmp.c_str(), &statbuf)) {
152 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
162 /* some directory someplace in the filesystem.
163 the snapshot name is the directory name
168 snapshot = str.substr (slash+1);
172 } else if (S_ISREG (statbuf.st_mode)) {
174 string::size_type slash = str.find_last_of ('/');
175 string::size_type suffix;
177 /* remove the suffix */
179 if (slash != string::npos) {
180 snapshot = str.substr (slash+1);
185 suffix = snapshot.find (_statefile_suffix);
187 if (suffix == string::npos) {
188 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
194 snapshot = snapshot.substr (0, suffix);
196 if (slash == string::npos) {
198 /* we must be in the directory where the
199 statefile lives. get it using cwd().
202 char cwd[PATH_MAX+1];
204 if (getcwd (cwd, sizeof (cwd)) == 0) {
205 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
214 /* full path to the statefile */
216 path = str.substr (0, slash);
221 /* what type of file is it? */
222 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
228 /* its the name of a new directory. get the name
232 string::size_type slash = str.find_last_of ('/');
234 if (slash == string::npos) {
236 /* no slash, just use the name, but clean it up */
238 path = legalize_for_path (str);
244 snapshot = str.substr (slash+1);
251 Session::Session (AudioEngine &eng,
253 string snapshot_name,
254 string* mix_template)
257 _mmc_port (default_mmc_port),
258 _mtc_port (default_mtc_port),
259 _midi_port (default_midi_port),
260 pending_events (2048),
261 //midi_requests (128), // the size of this should match the midi request pool size
262 _send_smpte_update (false),
267 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
269 n_physical_outputs = _engine.n_physical_outputs();
270 n_physical_inputs = _engine.n_physical_inputs();
272 first_stage_init (fullpath, snapshot_name);
274 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
275 throw failed_constructor ();
278 if (second_stage_init (new_session)) {
279 throw failed_constructor ();
282 store_recent_sessions(_name, _path);
284 bool was_dirty = dirty();
286 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
289 DirtyChanged (); /* EMIT SIGNAL */
293 Session::Session (AudioEngine &eng,
295 string snapshot_name,
296 AutoConnectOption input_ac,
297 AutoConnectOption output_ac,
298 uint32_t control_out_channels,
299 uint32_t master_out_channels,
300 uint32_t requested_physical_in,
301 uint32_t requested_physical_out,
302 jack_nframes_t initial_length)
305 _mmc_port (default_mmc_port),
306 _mtc_port (default_mtc_port),
307 _midi_port (default_midi_port),
308 pending_events (2048),
309 //midi_requests (16),
310 _send_smpte_update (false),
316 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
318 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
319 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
321 first_stage_init (fullpath, snapshot_name);
323 if (create (new_session, 0, initial_length)) {
324 throw failed_constructor ();
327 if (control_out_channels) {
329 r = new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut);
334 if (master_out_channels) {
336 r = new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut);
340 /* prohibit auto-connect to master, because there isn't one */
341 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
344 input_auto_connect = input_ac;
345 output_auto_connect = output_ac;
347 if (second_stage_init (new_session)) {
348 throw failed_constructor ();
351 store_recent_sessions(_name, _path);
353 bool was_dirty = dirty ();
355 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
358 DirtyChanged (); /* EMIT SIGNAL */
364 /* if we got to here, leaving pending capture state around
368 remove_pending_capture_state ();
370 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
371 _engine.remove_session ();
373 going_away (); /* EMIT SIGNAL */
375 terminate_butler_thread ();
376 //terminate_midi_thread ();
378 if (click_data && click_data != default_click) {
379 delete [] click_data;
382 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
383 delete [] click_emphasis_data;
397 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
401 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
405 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
409 for (map<RunContext,char*>::iterator i = _conversion_buffers.begin(); i != _conversion_buffers.end(); ++i) {
410 delete [] (i->second);
413 #undef TRACK_DESTRUCTION
414 #ifdef TRACK_DESTRUCTION
415 cerr << "delete named selections\n";
416 #endif /* TRACK_DESTRUCTION */
417 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
418 NamedSelectionList::iterator tmp;
427 #ifdef TRACK_DESTRUCTION
428 cerr << "delete playlists\n";
429 #endif /* TRACK_DESTRUCTION */
430 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
431 PlaylistList::iterator tmp;
441 #ifdef TRACK_DESTRUCTION
442 cerr << "delete audio regions\n";
443 #endif /* TRACK_DESTRUCTION */
444 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
445 AudioRegionList::iterator tmp;
455 #ifdef TRACK_DESTRUCTION
456 cerr << "delete routes\n";
457 #endif /* TRACK_DESTRUCTION */
458 for (RouteList::iterator i = routes.begin(); i != routes.end(); ) {
459 RouteList::iterator tmp;
466 #ifdef TRACK_DESTRUCTION
467 cerr << "delete diskstreams\n";
468 #endif /* TRACK_DESTRUCTION */
469 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
470 DiskstreamList::iterator tmp;
480 #ifdef TRACK_DESTRUCTION
481 cerr << "delete audio sources\n";
482 #endif /* TRACK_DESTRUCTION */
483 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
484 AudioSourceList::iterator tmp;
494 #ifdef TRACK_DESTRUCTION
495 cerr << "delete mix groups\n";
496 #endif /* TRACK_DESTRUCTION */
497 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
498 list<RouteGroup*>::iterator tmp;
508 #ifdef TRACK_DESTRUCTION
509 cerr << "delete edit groups\n";
510 #endif /* TRACK_DESTRUCTION */
511 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
512 list<RouteGroup*>::iterator tmp;
522 #ifdef TRACK_DESTRUCTION
523 cerr << "delete connections\n";
524 #endif /* TRACK_DESTRUCTION */
525 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
526 ConnectionList::iterator tmp;
536 if (butler_mixdown_buffer) {
537 delete [] butler_mixdown_buffer;
540 if (butler_gain_buffer) {
541 delete [] butler_gain_buffer;
544 Crossfade::set_buffer_size (0);
556 Session::set_worst_io_latencies (bool take_lock)
558 _worst_output_latency = 0;
559 _worst_input_latency = 0;
561 if (!_engine.connected()) {
566 route_lock.reader_lock ();
569 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
570 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
571 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
575 route_lock.reader_unlock ();
580 Session::when_engine_running ()
582 string first_physical_output;
584 /* we don't want to run execute this again */
586 first_time_running.disconnect ();
588 set_block_size (_engine.frames_per_cycle());
589 set_frame_rate (_engine.frame_rate());
591 /* every time we reconnect, recompute worst case output latencies */
593 _engine.Running.connect (sigc::bind (mem_fun (*this, &Session::set_worst_io_latencies), true));
595 if (synced_to_jack()) {
596 _engine.transport_stop ();
599 if (Config->get_jack_time_master()) {
600 _engine.transport_locate (_transport_frame);
608 _click_io = new ClickIO (*this, "click", 0, 0, -1, -1);
610 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
612 /* existing state for Click */
614 if (_click_io->set_state (*child->children().front()) == 0) {
616 _clicking = click_requested;
620 error << _("could not setup Click I/O") << endmsg;
626 /* default state for Click */
628 // FIXME: there's no JackPortIsAudio flag or anything like that, so this is _bad_.
629 // we need a get_nth_physical_audio_output or similar, but the existing one just
630 // deals with strings :/
632 first_physical_output = _engine.get_nth_physical_output (0);
633 cerr << "FIXME: click type" << endl;
635 if (first_physical_output.length()) {
636 if (_click_io->add_output_port (first_physical_output, this)) {
637 // relax, even though its an error
639 _clicking = click_requested;
645 catch (failed_constructor& err) {
646 error << _("cannot setup Click I/O") << endmsg;
649 set_worst_io_latencies (true);
652 ControlChanged (Clicking); /* EMIT SIGNAL */
655 if (auditioner == 0) {
657 /* we delay creating the auditioner till now because
658 it makes its own connections to ports named
659 in the ARDOUR_RC config file. the engine has
660 to be running for this to work.
664 auditioner = new Auditioner (*this);
667 catch (failed_constructor& err) {
668 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
672 /* Create a set of Connection objects that map
673 to the physical outputs currently available
678 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
680 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
682 Connection* c = new OutputConnection (buf, true);
685 c->add_connection (0, _engine.get_nth_physical_output (np));
690 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
692 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
694 Connection* c = new InputConnection (buf, true);
697 c->add_connection (0, _engine.get_nth_physical_input (np));
704 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
706 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
708 Connection* c = new OutputConnection (buf, true);
712 c->add_connection (0, _engine.get_nth_physical_output (np));
713 c->add_connection (1, _engine.get_nth_physical_output (np+1));
718 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
720 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
722 Connection* c = new InputConnection (buf, true);
726 c->add_connection (0, _engine.get_nth_physical_input (np));
727 c->add_connection (1, _engine.get_nth_physical_input (np+1));
736 /* create master/control ports */
741 /* force the master to ignore any later call to this */
743 if (_master_out->pending_state_node) {
744 _master_out->ports_became_legal();
747 /* no panner resets till we are through */
749 _master_out->defer_pan_reset ();
751 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
752 if (_master_out->add_input_port ("", this)) { // FIXME
753 error << _("cannot setup master inputs")
759 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
760 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) { // FIXME
761 error << _("cannot setup master outputs")
768 _master_out->allow_pan_reset ();
772 Connection* c = new OutputConnection (_("Master Out"), true);
774 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
776 c->add_connection ((int) n, _master_out->input(n)->name());
783 /* catch up on send+insert cnts */
787 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
790 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
791 if (id > insert_cnt) {
799 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
802 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
809 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
811 /* hook us up to the engine */
813 _engine.set_session (this);
818 osc->set_session (*this);
821 _state_of_the_state = Clean;
823 DirtyChanged (); /* EMIT SIGNAL */
827 Session::hookup_io ()
829 /* stop graph reordering notifications from
830 causing resorts, etc.
833 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
835 /* Tell all IO objects to create their ports */
842 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
843 if (_control_out->add_input_port ("", this)) {
844 error << _("cannot setup control inputs")
850 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
851 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
852 error << _("cannot set up master outputs")
860 /* Tell all IO objects to connect themselves together */
862 IO::enable_connecting ();
864 /* Now reset all panners */
866 IO::reset_panners ();
868 /* Anyone who cares about input state, wake up and do something */
870 IOConnectionsComplete (); /* EMIT SIGNAL */
872 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
874 /* now handle the whole enchilada as if it was one
880 /* update mixer solo state */
886 Session::playlist_length_changed (Playlist* pl)
888 /* we can't just increase end_location->end() if pl->get_maximum_extent()
889 if larger. if the playlist used to be the longest playlist,
890 and its now shorter, we have to decrease end_location->end(). hence,
891 we have to iterate over all diskstreams and check the
892 playlists currently in use.
898 Session::diskstream_playlist_changed (Diskstream* dstream)
902 if ((playlist = dstream->playlist()) != 0) {
903 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
906 /* see comment in playlist_length_changed () */
911 Session::record_enabling_legal () const
913 /* this used to be in here, but survey says.... we don't need to restrict it */
914 // if (record_status() == Recording) {
925 Session::set_auto_play (bool yn)
927 if (auto_play != yn) {
930 ControlChanged (AutoPlay);
935 Session::set_auto_return (bool yn)
937 if (auto_return != yn) {
940 ControlChanged (AutoReturn);
945 Session::set_crossfades_active (bool yn)
947 if (crossfades_active != yn) {
948 crossfades_active = yn;
950 ControlChanged (CrossFadesActive);
955 Session::set_do_not_record_plugins (bool yn)
957 if (do_not_record_plugins != yn) {
958 do_not_record_plugins = yn;
960 ControlChanged (RecordingPlugins);
965 Session::set_auto_input (bool yn)
967 if (auto_input != yn) {
970 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
971 /* auto-input only makes a difference if we're rolling */
973 /* Even though this can called from RT context we are using
974 a non-tentative rwlock here, because the action must occur.
975 The rarity and short potential lock duration makes this "OK"
977 Glib::RWLock::ReaderLock dsm (diskstream_lock);
978 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
979 if ((*i)->record_enabled ()) {
980 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
981 (*i)->monitor_input (!auto_input);
987 ControlChanged (AutoInput);
992 Session::reset_input_monitor_state ()
994 if (transport_rolling()) {
995 Glib::RWLock::ReaderLock dsm (diskstream_lock);
996 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
997 if ((*i)->record_enabled ()) {
998 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
999 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
1003 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1004 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1005 if ((*i)->record_enabled ()) {
1006 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1007 (*i)->monitor_input (Config->get_use_hardware_monitoring());
1015 Session::set_input_auto_connect (bool yn)
1018 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
1020 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1026 Session::get_input_auto_connect () const
1028 return (input_auto_connect & AutoConnectPhysical);
1032 Session::set_output_auto_connect (AutoConnectOption aco)
1034 output_auto_connect = aco;
1039 Session::auto_punch_start_changed (Location* location)
1041 replace_event (Event::PunchIn, location->start());
1043 if (get_record_enabled() && get_punch_in()) {
1044 /* capture start has been changed, so save new pending state */
1045 save_state ("", true);
1050 Session::auto_punch_end_changed (Location* location)
1052 jack_nframes_t when_to_stop = location->end();
1053 // when_to_stop += _worst_output_latency + _worst_input_latency;
1054 replace_event (Event::PunchOut, when_to_stop);
1058 Session::auto_punch_changed (Location* location)
1060 jack_nframes_t when_to_stop = location->end();
1062 replace_event (Event::PunchIn, location->start());
1063 //when_to_stop += _worst_output_latency + _worst_input_latency;
1064 replace_event (Event::PunchOut, when_to_stop);
1068 Session::auto_loop_changed (Location* location)
1070 replace_event (Event::AutoLoop, location->end(), location->start());
1072 if (transport_rolling() && get_auto_loop()) {
1074 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1076 if (_transport_frame > location->end()) {
1077 // relocate to beginning of loop
1078 clear_events (Event::LocateRoll);
1080 request_locate (location->start(), true);
1083 else if (seamless_loop && !loop_changing) {
1085 // schedule a locate-roll to refill the diskstreams at the
1086 // previous loop end
1087 loop_changing = true;
1089 if (location->end() > last_loopend) {
1090 clear_events (Event::LocateRoll);
1091 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1098 last_loopend = location->end();
1103 Session::set_auto_punch_location (Location* location)
1107 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1108 auto_punch_start_changed_connection.disconnect();
1109 auto_punch_end_changed_connection.disconnect();
1110 auto_punch_changed_connection.disconnect();
1111 existing->set_auto_punch (false, this);
1112 remove_event (existing->start(), Event::PunchIn);
1113 clear_events (Event::PunchOut);
1114 auto_punch_location_changed (0);
1119 if (location == 0) {
1123 if (location->end() <= location->start()) {
1124 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1128 auto_punch_start_changed_connection.disconnect();
1129 auto_punch_end_changed_connection.disconnect();
1130 auto_punch_changed_connection.disconnect();
1132 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1133 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1134 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1136 location->set_auto_punch (true, this);
1137 auto_punch_location_changed (location);
1141 Session::set_punch_in (bool yn)
1143 if (punch_in == yn) {
1149 if ((location = _locations.auto_punch_location()) != 0) {
1150 if ((punch_in = yn) == true) {
1151 replace_event (Event::PunchIn, location->start());
1153 remove_event (location->start(), Event::PunchIn);
1158 ControlChanged (PunchIn); /* EMIT SIGNAL */
1162 Session::set_punch_out (bool yn)
1164 if (punch_out == yn) {
1170 if ((location = _locations.auto_punch_location()) != 0) {
1171 if ((punch_out = yn) == true) {
1172 replace_event (Event::PunchOut, location->end());
1174 clear_events (Event::PunchOut);
1179 ControlChanged (PunchOut); /* EMIT SIGNAL */
1183 Session::set_auto_loop_location (Location* location)
1187 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1188 auto_loop_start_changed_connection.disconnect();
1189 auto_loop_end_changed_connection.disconnect();
1190 auto_loop_changed_connection.disconnect();
1191 existing->set_auto_loop (false, this);
1192 remove_event (existing->end(), Event::AutoLoop);
1193 auto_loop_location_changed (0);
1198 if (location == 0) {
1202 if (location->end() <= location->start()) {
1203 error << _("Session: you can't use a mark for auto loop") << endmsg;
1207 last_loopend = location->end();
1209 auto_loop_start_changed_connection.disconnect();
1210 auto_loop_end_changed_connection.disconnect();
1211 auto_loop_changed_connection.disconnect();
1213 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1214 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1215 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1217 location->set_auto_loop (true, this);
1218 auto_loop_location_changed (location);
1222 Session::locations_added (Location* ignored)
1228 Session::locations_changed ()
1230 _locations.apply (*this, &Session::handle_locations_changed);
1234 Session::handle_locations_changed (Locations::LocationList& locations)
1236 Locations::LocationList::iterator i;
1238 bool set_loop = false;
1239 bool set_punch = false;
1241 for (i = locations.begin(); i != locations.end(); ++i) {
1245 if (location->is_auto_punch()) {
1246 set_auto_punch_location (location);
1249 if (location->is_auto_loop()) {
1250 set_auto_loop_location (location);
1257 set_auto_loop_location (0);
1260 set_auto_punch_location (0);
1267 Session::enable_record ()
1269 /* XXX really atomic compare+swap here */
1270 if (g_atomic_int_get (&_record_status) != Recording) {
1271 g_atomic_int_set (&_record_status, Recording);
1272 _last_record_location = _transport_frame;
1273 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1275 if (Config->get_use_hardware_monitoring() && auto_input) {
1276 /* Even though this can be called from RT context we are using
1277 a non-tentative rwlock here, because the action must occur.
1278 The rarity and short potential lock duration makes this "OK"
1280 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1282 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1283 if ((*i)->record_enabled ()) {
1284 (*i)->monitor_input (true);
1289 RecordStateChanged ();
1294 Session::disable_record (bool rt_context, bool force)
1298 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1300 if (!Config->get_latched_record_enable () || force) {
1301 g_atomic_int_set (&_record_status, Disabled);
1303 if (rs == Recording) {
1304 g_atomic_int_set (&_record_status, Enabled);
1308 // FIXME: timestamp correct? [DR]
1309 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1310 // does this /need/ to be sent in all cases?
1312 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1314 if (Config->get_use_hardware_monitoring() && auto_input) {
1315 /* Even though this can be called from RT context we are using
1316 a non-tentative rwlock here, because the action must occur.
1317 The rarity and short potential lock duration makes this "OK"
1319 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1321 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1322 if ((*i)->record_enabled ()) {
1323 (*i)->monitor_input (false);
1328 RecordStateChanged (); /* emit signal */
1331 remove_pending_capture_state ();
1337 Session::step_back_from_record ()
1339 g_atomic_int_set (&_record_status, Enabled);
1341 if (Config->get_use_hardware_monitoring()) {
1342 /* Even though this can be called from RT context we are using
1343 a non-tentative rwlock here, because the action must occur.
1344 The rarity and short potential lock duration makes this "OK"
1346 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1348 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1349 if (auto_input && (*i)->record_enabled ()) {
1350 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1351 (*i)->monitor_input (false);
1358 Session::maybe_enable_record ()
1360 g_atomic_int_set (&_record_status, Enabled);
1362 /* XXX this save should really happen in another thread. its needed so that
1363 pending capture state can be recovered if we crash.
1366 save_state ("", true);
1368 if (_transport_speed) {
1373 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1374 RecordStateChanged (); /* EMIT SIGNAL */
1381 Session::audible_frame () const
1384 jack_nframes_t offset;
1387 /* the first of these two possible settings for "offset"
1388 mean that the audible frame is stationary until
1389 audio emerges from the latency compensation
1392 the second means that the audible frame is stationary
1393 until audio would emerge from a physical port
1394 in the absence of any plugin latency compensation
1397 offset = _worst_output_latency;
1399 if (offset > current_block_size) {
1400 offset -= current_block_size;
1402 /* XXX is this correct? if we have no external
1403 physical connections and everything is internal
1404 then surely this is zero? still, how
1405 likely is that anyway?
1407 offset = current_block_size;
1410 if (synced_to_jack()) {
1411 tf = _engine.transport_frame();
1413 tf = _transport_frame;
1416 if (_transport_speed == 0) {
1426 if (!non_realtime_work_pending()) {
1430 /* take latency into account */
1439 Session::set_frame_rate (jack_nframes_t frames_per_second)
1441 /** \fn void Session::set_frame_size(jack_nframes_t)
1442 the AudioEngine object that calls this guarantees
1443 that it will not be called while we are also in
1444 ::process(). Its fine to do things that block
1448 _current_frame_rate = frames_per_second;
1449 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1451 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1453 // XXX we need some equivalent to this, somehow
1454 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1458 /* XXX need to reset/reinstantiate all LADSPA plugins */
1462 Session::set_block_size (jack_nframes_t nframes)
1464 /* the AudioEngine guarantees
1465 that it will not be called while we are also in
1466 ::process(). It is therefore fine to do things that block
1471 Glib::RWLock::ReaderLock lm (route_lock);
1472 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1473 vector<Sample*>::iterator i;
1476 current_block_size = nframes;
1478 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1482 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1486 _passthru_buffers.clear ();
1487 _silent_buffers.clear ();
1489 ensure_passthru_buffers (np);
1491 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1495 #ifdef NO_POSIX_MEMALIGN
1496 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1498 posix_memalign((void **)&buf,16,current_block_size * 4);
1502 memset (*i, 0, sizeof (Sample) * current_block_size);
1506 if (_gain_automation_buffer) {
1507 delete [] _gain_automation_buffer;
1509 _gain_automation_buffer = new gain_t[nframes];
1511 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1513 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1514 (*i)->set_block_size (nframes);
1517 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1518 (*i)->set_block_size (nframes);
1521 set_worst_io_latencies (false);
1526 Session::set_default_fade (float steepness, float fade_msecs)
1529 jack_nframes_t fade_frames;
1531 /* Don't allow fade of less 1 frame */
1533 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1540 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1544 default_fade_msecs = fade_msecs;
1545 default_fade_steepness = steepness;
1548 // jlc, WTF is this!
1549 Glib::RWLock::ReaderLock lm (route_lock);
1550 AudioRegion::set_default_fade (steepness, fade_frames);
1555 /* XXX have to do this at some point */
1556 /* foreach region using default fade, reset, then
1557 refill_all_diskstream_buffers ();
1562 struct RouteSorter {
1563 bool operator() (Route* r1, Route* r2) {
1564 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1566 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1569 if (r1->fed_by.empty()) {
1570 if (r2->fed_by.empty()) {
1571 /* no ardour-based connections inbound to either route. just use signal order */
1572 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1574 /* r2 has connections, r1 does not; run r1 early */
1578 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1585 trace_terminal (Route* r1, Route* rbase)
1589 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1590 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1594 /* make a copy of the existing list of routes that feed r1 */
1596 set<Route *> existing = r1->fed_by;
1598 /* for each route that feeds r1, recurse, marking it as feeding
1602 for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
1605 /* r2 is a route that feeds r1 which somehow feeds base. mark
1606 base as being fed by r2
1609 rbase->fed_by.insert (r2);
1613 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1617 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1621 /* now recurse, so that we can mark base as being fed by
1622 all routes that feed r2
1625 trace_terminal (r2, rbase);
1632 Session::resort_routes (void* src)
1634 /* don't do anything here with signals emitted
1635 by Routes while we are being destroyed.
1638 if (_state_of_the_state & Deletion) {
1642 /* Caller MUST hold the route_lock */
1644 RouteList::iterator i, j;
1646 for (i = routes.begin(); i != routes.end(); ++i) {
1648 (*i)->fed_by.clear ();
1650 for (j = routes.begin(); j != routes.end(); ++j) {
1652 /* although routes can feed themselves, it will
1653 cause an endless recursive descent if we
1654 detect it. so don't bother checking for
1662 if ((*j)->feeds (*i)) {
1663 (*i)->fed_by.insert (*j);
1668 for (i = routes.begin(); i != routes.end(); ++i) {
1669 trace_terminal (*i, *i);
1676 cerr << "finished route resort\n";
1678 for (i = routes.begin(); i != routes.end(); ++i) {
1679 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1687 Session::new_midi_track (TrackMode mode)
1690 char track_name[32];
1692 uint32_t channels_used = 0;
1695 /* count existing midi tracks */
1698 Glib::RWLock::ReaderLock lm (route_lock);
1699 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1700 if (dynamic_cast<MidiTrack*>(*i) != 0) {
1701 if (!(*i)->hidden()) {
1703 channels_used += (*i)->n_inputs();
1709 /* check for duplicate route names, since we might have pre-existing
1710 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1711 save, close,restart,add new route - first named route is now
1716 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, n+1);
1717 if (route_by_name (track_name) == 0) {
1722 } while (n < (UINT_MAX-1));
1725 track = new MidiTrack (*this, track_name, Route::Flag (0), mode);
1727 if (track->ensure_io (1, 1, false, this)) {
1728 error << string_compose (_("cannot configure %1 in/%2 out configuration for new midi track"), track_name)
1733 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1737 if (input_auto_connect & AutoConnectPhysical) {
1738 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1741 if (port.length() && track->connect_input (track->input (x), port, this)) {
1747 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1751 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1752 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1753 } else if (output_auto_connect & AutoConnectMaster) {
1755 port = _master_out->input (x%_master_out->n_inputs())->name();
1759 if (port.length() && track->connect_output (track->output (x), port, this)) {
1765 vector<string> cports;
1766 uint32_t ni = _control_out->n_inputs();
1768 for (n = 0; n < ni; ++n) {
1769 cports.push_back (_control_out->input(n)->name());
1772 track->set_control_outs (cports);
1775 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1779 track->set_remote_control_id (ntracks());
1782 catch (failed_constructor &err) {
1783 error << _("Session: could not create new midi track.") << endmsg;
1792 Session::new_midi_route ()
1799 /* count existing midi busses */
1802 Glib::RWLock::ReaderLock lm (route_lock);
1803 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1804 if (dynamic_cast<MidiTrack*>(*i) == 0) {
1805 if (!(*i)->hidden()) {
1813 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1814 if (route_by_name (bus_name) == 0) {
1819 } while (n < (UINT_MAX-1));
1822 bus = new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), Buffer::MIDI);
1824 if (bus->ensure_io (1, 1, false, this)) {
1825 error << (_("cannot configure 1 in/1 out configuration for new midi track"))
1829 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1833 if (input_auto_connect & AutoConnectPhysical) {
1834 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1837 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1842 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1846 if (output_auto_connect & AutoConnectPhysical) {
1847 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1848 } else if (output_auto_connect & AutoConnectMaster) {
1850 port = _master_out->input (x%_master_out->n_inputs())->name();
1854 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1861 vector<string> cports;
1862 uint32_t ni = _control_out->n_inputs();
1864 for (uint32_t n = 0; n < ni; ++n) {
1865 cports.push_back (_control_out->input(n)->name());
1867 bus->set_control_outs (cports);
1873 catch (failed_constructor &err) {
1874 error << _("Session: could not create new MIDI route.") << endmsg;
1883 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1886 char track_name[32];
1888 uint32_t channels_used = 0;
1890 uint32_t nphysical_in;
1891 uint32_t nphysical_out;
1893 /* count existing audio tracks */
1896 Glib::RWLock::ReaderLock lm (route_lock);
1897 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1898 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1899 if (!(*i)->hidden()) {
1901 channels_used += (*i)->n_inputs();
1907 /* check for duplicate route names, since we might have pre-existing
1908 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1909 save, close,restart,add new route - first named route is now
1914 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1915 if (route_by_name (track_name) == 0) {
1920 } while (n < (UINT_MAX-1));
1922 if (input_auto_connect & AutoConnectPhysical) {
1923 nphysical_in = n_physical_inputs;
1928 if (output_auto_connect & AutoConnectPhysical) {
1929 nphysical_out = n_physical_outputs;
1935 track = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1937 if (track->ensure_io (input_channels, output_channels, false, this)) {
1938 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1939 input_channels, output_channels)
1944 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1948 if (input_auto_connect & AutoConnectPhysical) {
1949 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1952 if (port.length() && track->connect_input (track->input (x), port, this)) {
1958 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1962 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1963 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1964 } else if (output_auto_connect & AutoConnectMaster) {
1966 port = _master_out->input (x%_master_out->n_inputs())->name();
1970 if (port.length() && track->connect_output (track->output (x), port, this)) {
1976 vector<string> cports;
1977 uint32_t ni = _control_out->n_inputs();
1979 for (n = 0; n < ni; ++n) {
1980 cports.push_back (_control_out->input(n)->name());
1983 track->set_control_outs (cports);
1986 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1990 track->set_remote_control_id (ntracks());
1993 catch (failed_constructor &err) {
1994 error << _("Session: could not create new audio track.") << endmsg;
2002 Session::new_audio_route (int input_channels, int output_channels)
2009 /* count existing audio busses */
2012 Glib::RWLock::ReaderLock lm (route_lock);
2013 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2014 if (dynamic_cast<AudioTrack*>(*i) == 0) {
2015 if (!(*i)->hidden()) {
2023 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
2024 if (route_by_name (bus_name) == 0) {
2029 } while (n < (UINT_MAX-1));
2032 bus = new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), Buffer::AUDIO);
2034 if (bus->ensure_io (input_channels, output_channels, false, this)) {
2035 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
2036 input_channels, output_channels)
2040 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
2044 if (input_auto_connect & AutoConnectPhysical) {
2045 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
2048 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
2053 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
2057 if (output_auto_connect & AutoConnectPhysical) {
2058 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
2059 } else if (output_auto_connect & AutoConnectMaster) {
2061 port = _master_out->input (x%_master_out->n_inputs())->name();
2065 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
2071 vector<string> cports;
2072 uint32_t ni = _control_out->n_inputs();
2074 for (uint32_t n = 0; n < ni; ++n) {
2075 cports.push_back (_control_out->input(n)->name());
2077 bus->set_control_outs (cports);
2083 catch (failed_constructor &err) {
2084 error << _("Session: could not create new audio route.") << endmsg;
2092 Session::add_route (Route* route)
2095 Glib::RWLock::WriterLock lm (route_lock);
2096 routes.push_front (route);
2100 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
2101 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2102 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2103 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
2105 if (route->master()) {
2106 _master_out = route;
2109 if (route->control()) {
2110 _control_out = route;
2114 save_state (_current_snapshot_name);
2116 RouteAdded (route); /* EMIT SIGNAL */
2120 Session::add_diskstream (Diskstream* dstream)
2122 /* need to do this in case we're rolling at the time, to prevent false underruns */
2123 dstream->non_realtime_do_refill();
2126 Glib::RWLock::WriterLock lm (diskstream_lock);
2127 diskstreams.push_back (dstream);
2130 /* take a reference to the diskstream, preventing it from
2131 ever being deleted until the session itself goes away,
2132 or chooses to remove it for its own purposes.
2136 dstream->set_block_size (current_block_size);
2138 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2139 /* this will connect to future changes, and check the current length */
2140 diskstream_playlist_changed (dstream);
2142 dstream->prepare ();
2145 save_state (_current_snapshot_name);
2147 DiskstreamAdded (dstream); /* EMIT SIGNAL */
2151 Session::remove_route (Route& route)
2154 Glib::RWLock::WriterLock lm (route_lock);
2155 routes.remove (&route);
2157 /* deleting the master out seems like a dumb
2158 idea, but its more of a UI policy issue
2162 if (&route == _master_out) {
2166 if (&route == _control_out) {
2169 /* cancel control outs for all routes */
2171 vector<string> empty;
2173 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
2174 (*r)->set_control_outs (empty);
2178 update_route_solo_state ();
2182 AudioDiskstream* ds = 0;
2184 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
2185 ds = &at->disk_stream();
2191 Glib::RWLock::WriterLock lm (diskstream_lock);
2192 diskstreams.remove (ds);
2198 find_current_end ();
2200 update_latency_compensation (false, false);
2203 /* XXX should we disconnect from the Route's signals ? */
2205 save_state (_current_snapshot_name);
2211 Session::route_mute_changed (void* src)
2217 Session::route_solo_changed (void* src, Route* route)
2219 if (solo_update_disabled) {
2224 Glib::RWLock::ReaderLock lm (route_lock);
2227 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
2229 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2231 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2235 /* don't mess with busses */
2237 if (dynamic_cast<AudioTrack*>(*i) == 0) {
2243 /* don't mess with tracks */
2245 if (dynamic_cast<AudioTrack*>(*i) != 0) {
2250 if ((*i) != route &&
2251 ((*i)->mix_group () == 0 ||
2252 (*i)->mix_group () != route->mix_group () ||
2253 !route->mix_group ()->is_active())) {
2255 if ((*i)->soloed()) {
2257 /* if its already soloed, and solo latching is enabled,
2258 then leave it as it is.
2261 if (_solo_latched) {
2268 solo_update_disabled = true;
2269 (*i)->set_solo (false, src);
2270 solo_update_disabled = false;
2274 bool something_soloed = false;
2275 bool same_thing_soloed = false;
2276 bool signal = false;
2278 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2279 if ((*i)->soloed()) {
2280 something_soloed = true;
2281 if (dynamic_cast<AudioTrack*>(*i)) {
2283 same_thing_soloed = true;
2288 same_thing_soloed = true;
2296 if (something_soloed != currently_soloing) {
2298 currently_soloing = something_soloed;
2301 modify_solo_mute (is_track, same_thing_soloed);
2304 SoloActive (currently_soloing);
2311 Session::set_solo_latched (bool yn)
2313 if (yn != _solo_latched) {
2316 ControlChanged (SoloLatch);
2321 Session::update_route_solo_state ()
2324 bool is_track = false;
2325 bool signal = false;
2327 /* caller must hold RouteLock */
2329 /* this is where we actually implement solo by changing
2330 the solo mute setting of each track.
2333 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2334 if ((*i)->soloed()) {
2336 if (dynamic_cast<AudioTrack*>(*i)) {
2343 if (mute != currently_soloing) {
2345 currently_soloing = mute;
2348 if (!is_track && !mute) {
2350 /* nothing is soloed */
2352 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2353 (*i)->set_solo_mute (false);
2363 modify_solo_mute (is_track, mute);
2366 SoloActive (currently_soloing);
2371 Session::modify_solo_mute (bool is_track, bool mute)
2373 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2377 /* only alter track solo mute */
2379 if (dynamic_cast<AudioTrack*>(*i)) {
2380 if ((*i)->soloed()) {
2381 (*i)->set_solo_mute (!mute);
2383 (*i)->set_solo_mute (mute);
2389 /* only alter bus solo mute */
2391 if (!dynamic_cast<AudioTrack*>(*i)) {
2393 if ((*i)->soloed()) {
2395 (*i)->set_solo_mute (false);
2399 /* don't mute master or control outs
2400 in response to another bus solo
2403 if ((*i) != _master_out &&
2404 (*i) != _control_out) {
2405 (*i)->set_solo_mute (mute);
2416 Session::catch_up_on_solo ()
2418 /* this is called after set_state() to catch the full solo
2419 state, which can't be correctly determined on a per-route
2420 basis, but needs the global overview that only the session
2423 Glib::RWLock::ReaderLock lm (route_lock);
2424 update_route_solo_state();
2428 Session::route_by_name (string name)
2430 Glib::RWLock::ReaderLock lm (route_lock);
2432 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2433 if ((*i)->name() == name) {
2442 Session::route_by_remote_id (uint32_t id)
2444 Glib::RWLock::ReaderLock lm (route_lock);
2446 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2447 if ((*i)->remote_control_id() == id) {
2456 Session::find_current_end ()
2458 if (_state_of_the_state & Loading) {
2462 jack_nframes_t max = get_maximum_extent ();
2464 if (max > end_location->end()) {
2465 end_location->set_end (max);
2467 DurationChanged(); /* EMIT SIGNAL */
2472 Session::get_maximum_extent () const
2474 jack_nframes_t max = 0;
2477 /* Don't take the diskstream lock. Caller must have other ways to
2481 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2482 Playlist* pl = (*i)->playlist();
2483 if ((me = pl->get_maximum_extent()) > max) {
2492 Session::diskstream_by_name (string name)
2494 Glib::RWLock::ReaderLock lm (diskstream_lock);
2497 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2498 if ((*i)->name() == name) {
2507 Session::diskstream_by_id (const PBD::ID& id)
2509 Glib::RWLock::ReaderLock lm (diskstream_lock);
2512 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2513 if ((*i)->id() == id) {
2521 /* AudioRegion management */
2524 Session::new_region_name (string old)
2526 string::size_type last_period;
2528 string::size_type len = old.length() + 64;
2531 if ((last_period = old.find_last_of ('.')) == string::npos) {
2533 /* no period present - add one explicitly */
2536 last_period = old.length() - 1;
2541 number = atoi (old.substr (last_period+1).c_str());
2545 while (number < (UINT_MAX-1)) {
2547 AudioRegionList::const_iterator i;
2552 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2555 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2556 if (i->second->name() == sbuf) {
2561 if (i == audio_regions.end()) {
2566 if (number != (UINT_MAX-1)) {
2570 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2575 Session::region_name (string& result, string base, bool newlevel) const
2582 Glib::Mutex::Lock lm (region_lock);
2584 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2592 /* XXX this is going to be slow. optimize me later */
2597 string::size_type pos;
2599 pos = base.find_last_of ('.');
2601 /* pos may be npos, but then we just use entire base */
2603 subbase = base.substr (0, pos);
2607 bool name_taken = true;
2610 Glib::Mutex::Lock lm (region_lock);
2612 for (int n = 1; n < 5000; ++n) {
2615 snprintf (buf, sizeof (buf), ".%d", n);
2620 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2621 if (i->second->name() == result) {
2634 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2642 Session::add_region (Region* region)
2644 AudioRegion* ar = 0;
2645 AudioRegion* oar = 0;
2649 Glib::Mutex::Lock lm (region_lock);
2651 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2653 AudioRegionList::iterator x;
2655 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2657 oar = dynamic_cast<AudioRegion*> (x->second);
2659 if (ar->region_list_equivalent (*oar)) {
2664 if (x == audio_regions.end()) {
2666 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2668 entry.first = region->id();
2671 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2682 fatal << _("programming error: ")
2683 << X_("unknown region type passed to Session::add_region()")
2690 /* mark dirty because something has changed even if we didn't
2691 add the region to the region list.
2697 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2698 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2699 AudioRegionAdded (ar); /* EMIT SIGNAL */
2704 Session::region_changed (Change what_changed, Region* region)
2706 if (what_changed & Region::HiddenChanged) {
2707 /* relay hidden changes */
2708 RegionHiddenChange (region);
2713 Session::region_renamed (Region* region)
2715 add_region (region);
2719 Session::remove_region (Region* region)
2721 AudioRegionList::iterator i;
2722 AudioRegion* ar = 0;
2723 bool removed = false;
2726 Glib::Mutex::Lock lm (region_lock);
2728 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2729 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2730 audio_regions.erase (i);
2736 fatal << _("programming error: ")
2737 << X_("unknown region type passed to Session::remove_region()")
2743 /* mark dirty because something has changed even if we didn't
2744 remove the region from the region list.
2750 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2755 Session::find_whole_file_parent (AudioRegion& child)
2757 AudioRegionList::iterator i;
2758 AudioRegion* region;
2759 Glib::Mutex::Lock lm (region_lock);
2761 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2765 if (region->whole_file()) {
2767 if (child.source_equivalent (*region)) {
2777 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2779 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2783 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2787 pl->get_region_list_equivalent_regions (region, result);
2792 Session::destroy_region (Region* region)
2794 AudioRegion* aregion;
2796 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2800 if (aregion->playlist()) {
2801 aregion->playlist()->destroy_region (region);
2804 vector<Source*> srcs;
2806 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2807 srcs.push_back (&aregion->source (n));
2810 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2812 if ((*i)->use_cnt() == 0) {
2813 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2815 (afs)->mark_for_remove ();
2825 Session::destroy_regions (list<Region*> regions)
2827 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2828 destroy_region (*i);
2834 Session::remove_last_capture ()
2838 Glib::RWLock::ReaderLock lm (diskstream_lock);
2840 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2841 list<Region*>& l = (*i)->last_capture_regions();
2844 r.insert (r.end(), l.begin(), l.end());
2849 destroy_regions (r);
2854 Session::remove_region_from_region_list (Region& r)
2860 /* Source Management */
2863 Session::add_audio_source (AudioSource* source)
2865 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2868 Glib::Mutex::Lock lm (audio_source_lock);
2869 entry.first = source->id();
2870 entry.second = source;
2871 audio_sources.insert (entry);
2874 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2877 SourceAdded (source); /* EMIT SIGNAL */
2881 Session::remove_source (Source* source)
2883 AudioSourceList::iterator i;
2886 Glib::Mutex::Lock lm (audio_source_lock);
2888 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2889 audio_sources.erase (i);
2893 if (!_state_of_the_state & InCleanup) {
2895 /* save state so we don't end up with a session file
2896 referring to non-existent sources.
2899 save_state (_current_snapshot_name);
2902 SourceRemoved(source); /* EMIT SIGNAL */
2906 Session::source_by_id (const PBD::ID& id)
2908 Glib::Mutex::Lock lm (audio_source_lock);
2909 AudioSourceList::iterator i;
2912 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2916 /* XXX search MIDI or other searches here */
2922 Session::peak_path_from_audio_path (string audio_path)
2924 /* XXX hardly bombproof! fix me */
2928 res = Glib::path_get_dirname (audio_path);
2929 res = Glib::path_get_dirname (res);
2931 res += peak_dir_name;
2933 res += PBD::basename_nosuffix (audio_path);
2940 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2943 string old_basename = PBD::basename_nosuffix (oldname);
2944 string new_legalized = legalize_for_path (newname);
2946 /* note: we know (or assume) the old path is already valid */
2950 /* destructive file sources have a name of the form:
2952 /path/to/Tnnnn-NAME(%[LR])?.wav
2954 the task here is to replace NAME with the new name.
2957 /* find last slash */
2961 string::size_type slash;
2962 string::size_type dash;
2964 if ((slash = path.find_last_of ('/')) == string::npos) {
2968 dir = path.substr (0, slash+1);
2970 /* '-' is not a legal character for the NAME part of the path */
2972 if ((dash = path.find_last_of ('-')) == string::npos) {
2976 prefix = path.substr (slash+1, dash-(slash+1));
2981 path += new_legalized;
2982 path += ".wav"; /* XXX gag me with a spoon */
2986 /* non-destructive file sources have a name of the form:
2988 /path/to/NAME-nnnnn(%[LR])?.wav
2990 the task here is to replace NAME with the new name.
2993 /* find last slash */
2997 string::size_type slash;
2998 string::size_type dash;
3000 if ((slash = path.find_last_of ('/')) == string::npos) {
3004 dir = path.substr (0, slash+1);
3006 /* '-' is not a legal character for the NAME part of the path */
3008 if ((dash = path.find_last_of ('-')) == string::npos) {
3012 suffix = path.substr (dash);
3015 path += new_legalized;
3023 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
3027 char buf[PATH_MAX+1];
3028 const uint32_t limit = 10000;
3032 legalized = legalize_for_path (name);
3034 /* find a "version" of the file name that doesn't exist in
3035 any of the possible directories.
3038 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3040 vector<space_and_path>::iterator i;
3041 uint32_t existing = 0;
3043 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3048 spath += tape_dir_name;
3050 spath += sound_dir_name;
3055 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3056 } else if (nchan == 2) {
3058 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
3060 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
3062 } else if (nchan < 26) {
3063 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3065 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
3073 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3074 } else if (nchan == 2) {
3076 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3078 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3080 } else if (nchan < 26) {
3081 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3083 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3087 if (access (buf, F_OK) == 0) {
3092 if (existing == 0) {
3097 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3098 throw failed_constructor();
3102 /* we now have a unique name for the file, but figure out where to
3109 spath = tape_dir ();
3111 spath = discover_best_sound_dir ();
3114 string::size_type pos = foo.find_last_of ('/');
3116 if (pos == string::npos) {
3119 spath += foo.substr (pos + 1);
3126 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3128 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3130 /* this might throw failed_constructor(), which is OK */
3133 return new DestructiveFileSource (spath,
3134 Config->get_native_file_data_format(),
3135 Config->get_native_file_header_format(),
3138 return new SndFileSource (spath,
3139 Config->get_native_file_data_format(),
3140 Config->get_native_file_header_format(),
3145 /* Playlist management */
3148 Session::playlist_by_name (string name)
3150 Glib::Mutex::Lock lm (playlist_lock);
3151 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3152 if ((*i)->name() == name) {
3156 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3157 if ((*i)->name() == name) {
3165 Session::add_playlist (Playlist* playlist)
3167 if (playlist->hidden()) {
3172 Glib::Mutex::Lock lm (playlist_lock);
3173 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3174 playlists.insert (playlists.begin(), playlist);
3176 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3177 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
3183 PlaylistAdded (playlist); /* EMIT SIGNAL */
3187 Session::track_playlist (Playlist* pl, bool inuse)
3189 PlaylistList::iterator x;
3192 Glib::Mutex::Lock lm (playlist_lock);
3195 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3197 unused_playlists.insert (pl);
3199 if ((x = playlists.find (pl)) != playlists.end()) {
3200 playlists.erase (x);
3205 //cerr << "shifting playlist to used: " << pl->name() << endl;
3207 playlists.insert (pl);
3209 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3210 unused_playlists.erase (x);
3217 Session::remove_playlist (Playlist* playlist)
3219 if (_state_of_the_state & Deletion) {
3224 Glib::Mutex::Lock lm (playlist_lock);
3225 // cerr << "removing playlist: " << playlist->name() << endl;
3227 PlaylistList::iterator i;
3229 i = find (playlists.begin(), playlists.end(), playlist);
3231 if (i != playlists.end()) {
3232 playlists.erase (i);
3235 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3236 if (i != unused_playlists.end()) {
3237 unused_playlists.erase (i);
3244 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3248 Session::set_audition (AudioRegion* r)
3250 pending_audition_region = r;
3251 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3252 schedule_butler_transport_work ();
3256 Session::non_realtime_set_audition ()
3258 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3259 auditioner->audition_current_playlist ();
3260 } else if (pending_audition_region) {
3261 auditioner->audition_region (*pending_audition_region);
3263 pending_audition_region = 0;
3264 AuditionActive (true); /* EMIT SIGNAL */
3268 Session::audition_playlist ()
3270 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3271 ev->set_ptr ((void*) 0xfeedface);
3276 Session::audition_region (AudioRegion& r)
3278 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3284 Session::cancel_audition ()
3286 if (auditioner->active()) {
3287 auditioner->cancel_audition ();
3288 AuditionActive (false); /* EMIT SIGNAL */
3293 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
3295 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3299 Session::remove_empty_sounds ()
3302 PathScanner scanner;
3307 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3309 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3311 if (AudioFileSource::is_empty (*(*i))) {
3313 unlink ((*i)->c_str());
3315 string peak_path = peak_path_from_audio_path (**i);
3316 unlink (peak_path.c_str());
3322 delete possible_audiofiles;
3326 Session::is_auditioning () const
3328 /* can be called before we have an auditioner object */
3330 return auditioner->active();
3337 Session::set_all_solo (bool yn)
3340 Glib::RWLock::ReaderLock lm (route_lock);
3342 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3343 if (!(*i)->hidden()) {
3344 (*i)->set_solo (yn, this);
3353 Session::set_all_mute (bool yn)
3356 Glib::RWLock::ReaderLock lm (route_lock);
3358 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3359 if (!(*i)->hidden()) {
3360 (*i)->set_mute (yn, this);
3369 Session::n_diskstreams () const
3371 Glib::RWLock::ReaderLock lm (diskstream_lock);
3374 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3375 if (!(*i)->hidden()) {
3383 Session::foreach_audio_diskstream (void (AudioDiskstream::*func)(void))
3385 Glib::RWLock::ReaderLock lm (diskstream_lock);
3386 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3387 if (!(*i)->hidden()) {
3395 Session::graph_reordered ()
3397 /* don't do this stuff if we are setting up connections
3398 from a set_state() call.
3401 if (_state_of_the_state & InitialConnecting) {
3405 Glib::RWLock::WriterLock lm1 (route_lock);
3406 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3410 /* force all diskstreams to update their capture offset values to
3411 reflect any changes in latencies within the graph.
3414 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3415 (*i)->set_capture_offset ();
3420 Session::record_disenable_all ()
3422 record_enable_change_all (false);
3426 Session::record_enable_all ()
3428 record_enable_change_all (true);
3432 Session::record_enable_change_all (bool yn)
3434 Glib::RWLock::ReaderLock lm1 (route_lock);
3436 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3439 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3440 at->set_record_enable (yn, this);
3444 /* since we don't keep rec-enable state, don't mark session dirty */
3448 Session::add_redirect (Redirect* redirect)
3452 PortInsert* port_insert;
3453 PluginInsert* plugin_insert;
3455 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3456 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3457 _port_inserts.insert (_port_inserts.begin(), port_insert);
3458 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3459 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3461 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3464 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3465 _sends.insert (_sends.begin(), send);
3467 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3471 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3477 Session::remove_redirect (Redirect* redirect)
3481 PortInsert* port_insert;
3482 PluginInsert* plugin_insert;
3484 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3485 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3486 _port_inserts.remove (port_insert);
3487 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3488 _plugin_inserts.remove (plugin_insert);
3490 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3493 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3494 _sends.remove (send);
3496 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3504 Session::available_capture_duration ()
3506 const double scale = 4096.0 / sizeof (Sample);
3508 if (_total_free_4k_blocks * scale > (double) max_frames) {
3512 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3516 Session::add_connection (ARDOUR::Connection* connection)
3519 Glib::Mutex::Lock guard (connection_lock);
3520 _connections.push_back (connection);
3523 ConnectionAdded (connection); /* EMIT SIGNAL */
3529 Session::remove_connection (ARDOUR::Connection* connection)
3531 bool removed = false;
3534 Glib::Mutex::Lock guard (connection_lock);
3535 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3537 if (i != _connections.end()) {
3538 _connections.erase (i);
3544 ConnectionRemoved (connection); /* EMIT SIGNAL */
3550 ARDOUR::Connection *
3551 Session::connection_by_name (string name) const
3553 Glib::Mutex::Lock lm (connection_lock);
3555 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3556 if ((*i)->name() == name) {
3565 Session::set_edit_mode (EditMode mode)
3570 Glib::Mutex::Lock lm (playlist_lock);
3572 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3573 (*i)->set_edit_mode (mode);
3578 ControlChanged (EditingMode); /* EMIT SIGNAL */
3582 Session::tempo_map_changed (Change ignored)
3589 Session::ensure_passthru_buffers (uint32_t howmany)
3591 while (howmany > _passthru_buffers.size()) {
3593 #ifdef NO_POSIX_MEMALIGN
3594 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3596 posix_memalign((void **)&p,16,current_block_size * 4);
3598 _passthru_buffers.push_back (p);
3602 #ifdef NO_POSIX_MEMALIGN
3603 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3605 posix_memalign((void **)&p,16,current_block_size * 4);
3607 memset (p, 0, sizeof (Sample) * current_block_size);
3608 _silent_buffers.push_back (p);
3612 #ifdef NO_POSIX_MEMALIGN
3613 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3615 posix_memalign((void **)&p,16,current_block_size * 4);
3617 memset (p, 0, sizeof (Sample) * current_block_size);
3618 _send_buffers.push_back (p);
3621 allocate_pan_automation_buffers (current_block_size, howmany, false);
3625 Session::next_send_name ()
3628 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3633 Session::next_insert_name ()
3636 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3640 /* Named Selection management */
3643 Session::named_selection_by_name (string name)
3645 Glib::Mutex::Lock lm (named_selection_lock);
3646 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3647 if ((*i)->name == name) {
3655 Session::add_named_selection (NamedSelection* named_selection)
3658 Glib::Mutex::Lock lm (named_selection_lock);
3659 named_selections.insert (named_selections.begin(), named_selection);
3664 NamedSelectionAdded (); /* EMIT SIGNAL */
3668 Session::remove_named_selection (NamedSelection* named_selection)
3670 bool removed = false;
3673 Glib::Mutex::Lock lm (named_selection_lock);
3675 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3677 if (i != named_selections.end()) {
3679 named_selections.erase (i);
3686 NamedSelectionRemoved (); /* EMIT SIGNAL */
3691 Session::reset_native_file_format ()
3693 // jlc - WHY take routelock?
3694 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3695 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3697 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3698 (*i)->reset_write_sources (false);
3703 Session::route_name_unique (string n) const
3705 Glib::RWLock::ReaderLock lm (route_lock);
3707 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3708 if ((*i)->name() == n) {
3717 Session::cleanup_audio_file_source (AudioFileSource& fs)
3719 return fs.move_to_trash (dead_sound_dir_name);
3723 Session::n_playlists () const
3725 Glib::Mutex::Lock lm (playlist_lock);
3726 return playlists.size();
3730 Session::set_solo_model (SoloModel sm)
3732 if (sm != _solo_model) {
3734 ControlChanged (SoloingModel);
3740 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3742 if (!force && howmany <= _npan_buffers) {
3746 if (_pan_automation_buffer) {
3748 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3749 delete [] _pan_automation_buffer[i];
3752 delete [] _pan_automation_buffer;
3755 _pan_automation_buffer = new pan_t*[howmany];
3757 for (uint32_t i = 0; i < howmany; ++i) {
3758 _pan_automation_buffer[i] = new pan_t[nframes];
3761 _npan_buffers = howmany;
3765 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3767 Stateful::add_instant_xml (node, dir);
3768 Config->add_instant_xml (node, get_user_ardour_path());
3772 Session::freeze (InterThreadInfo& itt)
3774 Glib::RWLock::ReaderLock lm (route_lock);
3776 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3780 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3781 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3792 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3793 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3797 AudioFileSource* fsource;
3799 char buf[PATH_MAX+1];
3802 jack_nframes_t position;
3803 jack_nframes_t this_chunk;
3804 jack_nframes_t to_do;
3805 vector<Sample*> buffers;
3808 // any bigger than this seems to cause stack overflows in called functions
3809 const jack_nframes_t chunk_size = (128 * 1024)/4;
3811 g_atomic_int_set (&processing_prohibited, 1);
3813 /* call tree *MUST* hold route_lock */
3815 if ((playlist = track.disk_stream().playlist()) == 0) {
3819 /* external redirects will be a problem */
3821 if (track.has_external_redirects()) {
3825 nchans = track.disk_stream().n_channels();
3827 dir = discover_best_sound_dir ();
3829 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3831 for (x = 0; x < 99999; ++x) {
3832 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3833 if (access (buf, F_OK) != 0) {
3839 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3844 fsource = new SndFileSource (buf,
3845 Config->get_native_file_data_format(),
3846 Config->get_native_file_header_format(),
3851 catch (failed_constructor& err) {
3852 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3856 srcs.push_back(fsource);
3859 /* XXX need to flush all redirects */
3864 /* create a set of reasonably-sized buffers */
3866 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3868 #ifdef NO_POSIX_MEMALIGN
3869 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3871 posix_memalign((void **)&b,16,chunk_size * 4);
3873 buffers.push_back (b);
3876 workbuf = new char[chunk_size * 4];
3878 while (to_do && !itt.cancel) {
3880 this_chunk = min (to_do, chunk_size);
3882 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3887 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3888 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3891 if (afs->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3897 start += this_chunk;
3898 to_do -= this_chunk;
3900 itt.progress = (float) (1.0 - ((double) to_do / len));
3909 xnow = localtime (&now);
3911 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3912 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3914 afs->update_header (position, *xnow, now);
3918 /* build peakfile for new source */
3920 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3921 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3923 afs->build_peaks ();
3932 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3933 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3935 afs->mark_for_remove ();
3941 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3949 g_atomic_int_set (&processing_prohibited, 0);
3957 Session::get_silent_buffers (uint32_t howmany)
3959 for (uint32_t i = 0; i < howmany; ++i) {
3960 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3962 return _silent_buffers;
3966 Session::ntracks () const
3969 Glib::RWLock::ReaderLock lm (route_lock);
3971 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3972 if (dynamic_cast<AudioTrack*> (*i)) {
3981 Session::nbusses () const
3984 Glib::RWLock::ReaderLock lm (route_lock);
3986 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3987 if (dynamic_cast<AudioTrack*> (*i) == 0) {
3996 Session::set_layer_model (LayerModel lm)
3998 if (lm != layer_model) {
4001 ControlChanged (LayeringModel);
4006 Session::set_xfade_model (CrossfadeModel xm)
4008 if (xm != xfade_model) {
4011 ControlChanged (CrossfadingModel);