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>
69 #include <ardour/osc.h>
75 using namespace ARDOUR;
77 using boost::shared_ptr;
79 const char* Session::_template_suffix = X_(".template");
80 const char* Session::_statefile_suffix = X_(".ardour");
81 const char* Session::_pending_suffix = X_(".pending");
82 const char* Session::sound_dir_name = X_("sounds");
83 const char* Session::tape_dir_name = X_("tapes");
84 const char* Session::peak_dir_name = X_("peaks");
85 const char* Session::dead_sound_dir_name = X_("dead_sounds");
87 Session::compute_peak_t Session::compute_peak = 0;
88 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
89 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
90 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
92 sigc::signal<int> Session::AskAboutPendingState;
93 sigc::signal<void> Session::SMPTEOffsetChanged;
94 sigc::signal<void> Session::SendFeedback;
98 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
101 char buf[PATH_MAX+1];
105 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
106 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
112 /* check to see if it exists, and what it is */
114 if (stat (str.c_str(), &statbuf)) {
115 if (errno == ENOENT) {
118 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
126 /* it exists, so it must either be the name
127 of the directory, or the name of the statefile
131 if (S_ISDIR (statbuf.st_mode)) {
133 string::size_type slash = str.find_last_of ('/');
135 if (slash == string::npos) {
137 /* a subdirectory of cwd, so statefile should be ... */
143 tmp += _statefile_suffix;
147 if (stat (tmp.c_str(), &statbuf)) {
148 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
158 /* some directory someplace in the filesystem.
159 the snapshot name is the directory name
164 snapshot = str.substr (slash+1);
168 } else if (S_ISREG (statbuf.st_mode)) {
170 string::size_type slash = str.find_last_of ('/');
171 string::size_type suffix;
173 /* remove the suffix */
175 if (slash != string::npos) {
176 snapshot = str.substr (slash+1);
181 suffix = snapshot.find (_statefile_suffix);
183 if (suffix == string::npos) {
184 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
190 snapshot = snapshot.substr (0, suffix);
192 if (slash == string::npos) {
194 /* we must be in the directory where the
195 statefile lives. get it using cwd().
198 char cwd[PATH_MAX+1];
200 if (getcwd (cwd, sizeof (cwd)) == 0) {
201 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
210 /* full path to the statefile */
212 path = str.substr (0, slash);
217 /* what type of file is it? */
218 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
224 /* its the name of a new directory. get the name
228 string::size_type slash = str.find_last_of ('/');
230 if (slash == string::npos) {
232 /* no slash, just use the name, but clean it up */
234 path = legalize_for_path (str);
240 snapshot = str.substr (slash+1);
247 Session::Session (AudioEngine &eng,
249 string snapshot_name,
250 string* mix_template)
253 _mmc_port (default_mmc_port),
254 _mtc_port (default_mtc_port),
255 _midi_port (default_midi_port),
256 pending_events (2048),
257 midi_requests (128), // the size of this should match the midi request pool size
258 routes (new RouteList),
259 auditioner ((Auditioner*) 0),
265 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
267 n_physical_outputs = _engine.n_physical_outputs();
268 n_physical_inputs = _engine.n_physical_inputs();
270 first_stage_init (fullpath, snapshot_name);
272 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
273 throw failed_constructor ();
276 if (second_stage_init (new_session)) {
277 throw failed_constructor ();
280 store_recent_sessions(_name, _path);
282 bool was_dirty = dirty();
284 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
287 DirtyChanged (); /* EMIT SIGNAL */
291 Session::Session (AudioEngine &eng,
293 string snapshot_name,
294 AutoConnectOption input_ac,
295 AutoConnectOption output_ac,
296 uint32_t control_out_channels,
297 uint32_t master_out_channels,
298 uint32_t requested_physical_in,
299 uint32_t requested_physical_out,
300 jack_nframes_t initial_length)
303 _mmc_port (default_mmc_port),
304 _mtc_port (default_mtc_port),
305 _midi_port (default_midi_port),
306 pending_events (2048),
308 routes (new RouteList),
314 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
316 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
317 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
319 first_stage_init (fullpath, snapshot_name);
321 if (create (new_session, 0, initial_length)) {
322 throw failed_constructor ();
325 if (control_out_channels) {
326 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
331 if (master_out_channels) {
332 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
336 /* prohibit auto-connect to master, because there isn't one */
337 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
340 input_auto_connect = input_ac;
341 output_auto_connect = output_ac;
343 if (second_stage_init (new_session)) {
344 throw failed_constructor ();
347 store_recent_sessions(_name, _path);
349 bool was_dirty = dirty ();
351 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
354 DirtyChanged (); /* EMIT SIGNAL */
360 /* if we got to here, leaving pending capture state around
364 remove_pending_capture_state ();
366 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
367 _engine.remove_session ();
369 going_away (); /* EMIT SIGNAL */
371 terminate_butler_thread ();
372 terminate_midi_thread ();
374 if (click_data && click_data != default_click) {
375 delete [] click_data;
378 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
379 delete [] click_emphasis_data;
384 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
388 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
392 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
396 for (map<RunContext,char*>::iterator i = _conversion_buffers.begin(); i != _conversion_buffers.end(); ++i) {
397 delete [] (i->second);
400 #undef TRACK_DESTRUCTION
401 #ifdef TRACK_DESTRUCTION
402 cerr << "delete named selections\n";
403 #endif /* TRACK_DESTRUCTION */
404 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
405 NamedSelectionList::iterator tmp;
414 #ifdef TRACK_DESTRUCTION
415 cerr << "delete playlists\n";
416 #endif /* TRACK_DESTRUCTION */
417 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
418 PlaylistList::iterator tmp;
428 #ifdef TRACK_DESTRUCTION
429 cerr << "delete audio regions\n";
430 #endif /* TRACK_DESTRUCTION */
431 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
432 AudioRegionList::iterator tmp;
442 #ifdef TRACK_DESTRUCTION
443 cerr << "delete audio_diskstreams\n";
444 #endif /* TRACK_DESTRUCTION */
445 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ) {
446 AudioDiskstreamList::iterator tmp;
456 #ifdef TRACK_DESTRUCTION
457 cerr << "delete audio sources\n";
458 #endif /* TRACK_DESTRUCTION */
459 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
460 AudioSourceList::iterator tmp;
470 #ifdef TRACK_DESTRUCTION
471 cerr << "delete mix groups\n";
472 #endif /* TRACK_DESTRUCTION */
473 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
474 list<RouteGroup*>::iterator tmp;
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete edit groups\n";
486 #endif /* TRACK_DESTRUCTION */
487 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
488 list<RouteGroup*>::iterator tmp;
498 #ifdef TRACK_DESTRUCTION
499 cerr << "delete connections\n";
500 #endif /* TRACK_DESTRUCTION */
501 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
502 ConnectionList::iterator tmp;
512 if (butler_mixdown_buffer) {
513 delete [] butler_mixdown_buffer;
516 if (butler_gain_buffer) {
517 delete [] butler_gain_buffer;
520 Crossfade::set_buffer_size (0);
532 Session::set_worst_io_latencies ()
534 _worst_output_latency = 0;
535 _worst_input_latency = 0;
537 if (!_engine.connected()) {
541 boost::shared_ptr<RouteList> r = routes.reader ();
543 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
544 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
545 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
550 Session::when_engine_running ()
552 string first_physical_output;
554 /* we don't want to run execute this again */
556 first_time_running.disconnect ();
558 set_block_size (_engine.frames_per_cycle());
559 set_frame_rate (_engine.frame_rate());
561 /* every time we reconnect, recompute worst case output latencies */
563 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
565 if (synced_to_jack()) {
566 _engine.transport_stop ();
569 if (Config->get_jack_time_master()) {
570 _engine.transport_locate (_transport_frame);
578 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
580 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
582 /* existing state for Click */
584 if (_click_io->set_state (*child->children().front()) == 0) {
586 _clicking = click_requested;
590 error << _("could not setup Click I/O") << endmsg;
596 /* default state for Click */
598 first_physical_output = _engine.get_nth_physical_output (0);
600 if (first_physical_output.length()) {
601 if (_click_io->add_output_port (first_physical_output, this)) {
602 // relax, even though its an error
604 _clicking = click_requested;
610 catch (failed_constructor& err) {
611 error << _("cannot setup Click I/O") << endmsg;
614 set_worst_io_latencies ();
617 ControlChanged (Clicking); /* EMIT SIGNAL */
620 if (auditioner == 0) {
622 /* we delay creating the auditioner till now because
623 it makes its own connections to ports named
624 in the ARDOUR_RC config file. the engine has
625 to be running for this to work.
629 auditioner.reset (new Auditioner (*this));
632 catch (failed_constructor& err) {
633 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
637 /* Create a set of Connection objects that map
638 to the physical outputs currently available
643 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
645 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
647 Connection* c = new OutputConnection (buf, true);
650 c->add_connection (0, _engine.get_nth_physical_output (np));
655 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
657 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
659 Connection* c = new InputConnection (buf, true);
662 c->add_connection (0, _engine.get_nth_physical_input (np));
669 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
671 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
673 Connection* c = new OutputConnection (buf, true);
677 c->add_connection (0, _engine.get_nth_physical_output (np));
678 c->add_connection (1, _engine.get_nth_physical_output (np+1));
683 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
685 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
687 Connection* c = new InputConnection (buf, true);
691 c->add_connection (0, _engine.get_nth_physical_input (np));
692 c->add_connection (1, _engine.get_nth_physical_input (np+1));
701 /* create master/control ports */
706 /* force the master to ignore any later call to this */
708 if (_master_out->pending_state_node) {
709 _master_out->ports_became_legal();
712 /* no panner resets till we are through */
714 _master_out->defer_pan_reset ();
716 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
717 if (_master_out->add_input_port ("", this)) {
718 error << _("cannot setup master inputs")
724 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
725 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
726 error << _("cannot setup master outputs")
733 _master_out->allow_pan_reset ();
737 Connection* c = new OutputConnection (_("Master Out"), true);
739 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
741 c->add_connection ((int) n, _master_out->input(n)->name());
748 /* catch up on send+insert cnts */
752 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
755 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
756 if (id > insert_cnt) {
764 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
767 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
774 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
776 /* hook us up to the engine */
778 _engine.set_session (this);
783 osc->set_session (*this);
786 _state_of_the_state = Clean;
788 DirtyChanged (); /* EMIT SIGNAL */
792 Session::hookup_io ()
794 /* stop graph reordering notifications from
795 causing resorts, etc.
798 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
800 /* Tell all IO objects to create their ports */
807 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
808 if (_control_out->add_input_port ("", this)) {
809 error << _("cannot setup control inputs")
815 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
816 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
817 error << _("cannot set up master outputs")
825 /* Tell all IO objects to connect themselves together */
827 IO::enable_connecting ();
829 /* Now reset all panners */
831 IO::reset_panners ();
833 /* Anyone who cares about input state, wake up and do something */
835 IOConnectionsComplete (); /* EMIT SIGNAL */
837 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
839 /* now handle the whole enchilada as if it was one
845 /* update mixer solo state */
851 Session::playlist_length_changed (Playlist* pl)
853 /* we can't just increase end_location->end() if pl->get_maximum_extent()
854 if larger. if the playlist used to be the longest playlist,
855 and its now shorter, we have to decrease end_location->end(). hence,
856 we have to iterate over all diskstreams and check the
857 playlists currently in use.
863 Session::diskstream_playlist_changed (AudioDiskstream* dstream)
867 if ((playlist = dstream->playlist()) != 0) {
868 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
871 /* see comment in playlist_length_changed () */
876 Session::record_enabling_legal () const
878 /* this used to be in here, but survey says.... we don't need to restrict it */
879 // if (record_status() == Recording) {
890 Session::set_auto_play (bool yn)
892 if (auto_play != yn) {
895 ControlChanged (AutoPlay);
900 Session::set_auto_return (bool yn)
902 if (auto_return != yn) {
905 ControlChanged (AutoReturn);
910 Session::set_crossfades_active (bool yn)
912 if (crossfades_active != yn) {
913 crossfades_active = yn;
915 ControlChanged (CrossFadesActive);
920 Session::set_do_not_record_plugins (bool yn)
922 if (do_not_record_plugins != yn) {
923 do_not_record_plugins = yn;
925 ControlChanged (RecordingPlugins);
930 Session::set_auto_input (bool yn)
932 if (auto_input != yn) {
935 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
936 /* auto-input only makes a difference if we're rolling */
938 /* Even though this can called from RT context we are using
939 a non-tentative rwlock here, because the action must occur.
940 The rarity and short potential lock duration makes this "OK"
942 Glib::RWLock::ReaderLock dsm (diskstream_lock);
943 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
944 if ((*i)->record_enabled ()) {
945 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
946 (*i)->monitor_input (!auto_input);
952 ControlChanged (AutoInput);
957 Session::reset_input_monitor_state ()
959 if (transport_rolling()) {
960 Glib::RWLock::ReaderLock dsm (diskstream_lock);
961 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
962 if ((*i)->record_enabled ()) {
963 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
964 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
968 Glib::RWLock::ReaderLock dsm (diskstream_lock);
969 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
970 if ((*i)->record_enabled ()) {
971 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
972 (*i)->monitor_input (Config->get_use_hardware_monitoring());
980 Session::set_input_auto_connect (bool yn)
983 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
985 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
991 Session::get_input_auto_connect () const
993 return (input_auto_connect & AutoConnectPhysical);
997 Session::set_output_auto_connect (AutoConnectOption aco)
999 output_auto_connect = aco;
1004 Session::auto_punch_start_changed (Location* location)
1006 replace_event (Event::PunchIn, location->start());
1008 if (get_record_enabled() && get_punch_in()) {
1009 /* capture start has been changed, so save new pending state */
1010 save_state ("", true);
1015 Session::auto_punch_end_changed (Location* location)
1017 jack_nframes_t when_to_stop = location->end();
1018 // when_to_stop += _worst_output_latency + _worst_input_latency;
1019 replace_event (Event::PunchOut, when_to_stop);
1023 Session::auto_punch_changed (Location* location)
1025 jack_nframes_t when_to_stop = location->end();
1027 replace_event (Event::PunchIn, location->start());
1028 //when_to_stop += _worst_output_latency + _worst_input_latency;
1029 replace_event (Event::PunchOut, when_to_stop);
1033 Session::auto_loop_changed (Location* location)
1035 replace_event (Event::AutoLoop, location->end(), location->start());
1037 if (transport_rolling() && get_auto_loop()) {
1039 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1041 if (_transport_frame > location->end()) {
1042 // relocate to beginning of loop
1043 clear_events (Event::LocateRoll);
1045 request_locate (location->start(), true);
1048 else if (seamless_loop && !loop_changing) {
1050 // schedule a locate-roll to refill the audio_diskstreams at the
1051 // previous loop end
1052 loop_changing = true;
1054 if (location->end() > last_loopend) {
1055 clear_events (Event::LocateRoll);
1056 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1063 last_loopend = location->end();
1068 Session::set_auto_punch_location (Location* location)
1072 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1073 auto_punch_start_changed_connection.disconnect();
1074 auto_punch_end_changed_connection.disconnect();
1075 auto_punch_changed_connection.disconnect();
1076 existing->set_auto_punch (false, this);
1077 remove_event (existing->start(), Event::PunchIn);
1078 clear_events (Event::PunchOut);
1079 auto_punch_location_changed (0);
1084 if (location == 0) {
1088 if (location->end() <= location->start()) {
1089 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1093 auto_punch_start_changed_connection.disconnect();
1094 auto_punch_end_changed_connection.disconnect();
1095 auto_punch_changed_connection.disconnect();
1097 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1098 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1099 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1101 location->set_auto_punch (true, this);
1102 auto_punch_location_changed (location);
1106 Session::set_punch_in (bool yn)
1108 if (punch_in == yn) {
1114 if ((location = _locations.auto_punch_location()) != 0) {
1115 if ((punch_in = yn) == true) {
1116 replace_event (Event::PunchIn, location->start());
1118 remove_event (location->start(), Event::PunchIn);
1123 ControlChanged (PunchIn); /* EMIT SIGNAL */
1127 Session::set_punch_out (bool yn)
1129 if (punch_out == yn) {
1135 if ((location = _locations.auto_punch_location()) != 0) {
1136 if ((punch_out = yn) == true) {
1137 replace_event (Event::PunchOut, location->end());
1139 clear_events (Event::PunchOut);
1144 ControlChanged (PunchOut); /* EMIT SIGNAL */
1148 Session::set_auto_loop_location (Location* location)
1152 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1153 auto_loop_start_changed_connection.disconnect();
1154 auto_loop_end_changed_connection.disconnect();
1155 auto_loop_changed_connection.disconnect();
1156 existing->set_auto_loop (false, this);
1157 remove_event (existing->end(), Event::AutoLoop);
1158 auto_loop_location_changed (0);
1163 if (location == 0) {
1167 if (location->end() <= location->start()) {
1168 error << _("Session: you can't use a mark for auto loop") << endmsg;
1172 last_loopend = location->end();
1174 auto_loop_start_changed_connection.disconnect();
1175 auto_loop_end_changed_connection.disconnect();
1176 auto_loop_changed_connection.disconnect();
1178 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1179 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1180 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1182 location->set_auto_loop (true, this);
1183 auto_loop_location_changed (location);
1187 Session::locations_added (Location* ignored)
1193 Session::locations_changed ()
1195 _locations.apply (*this, &Session::handle_locations_changed);
1199 Session::handle_locations_changed (Locations::LocationList& locations)
1201 Locations::LocationList::iterator i;
1203 bool set_loop = false;
1204 bool set_punch = false;
1206 for (i = locations.begin(); i != locations.end(); ++i) {
1210 if (location->is_auto_punch()) {
1211 set_auto_punch_location (location);
1214 if (location->is_auto_loop()) {
1215 set_auto_loop_location (location);
1222 set_auto_loop_location (0);
1225 set_auto_punch_location (0);
1232 Session::enable_record ()
1234 /* XXX really atomic compare+swap here */
1235 if (g_atomic_int_get (&_record_status) != Recording) {
1236 g_atomic_int_set (&_record_status, Recording);
1237 _last_record_location = _transport_frame;
1238 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1240 if (Config->get_use_hardware_monitoring() && auto_input) {
1241 /* Even though this can be called from RT context we are using
1242 a non-tentative rwlock here, because the action must occur.
1243 The rarity and short potential lock duration makes this "OK"
1245 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1247 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
1248 if ((*i)->record_enabled ()) {
1249 (*i)->monitor_input (true);
1254 RecordStateChanged ();
1259 Session::disable_record (bool rt_context, bool force)
1263 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1265 if (!Config->get_latched_record_enable () || force) {
1266 g_atomic_int_set (&_record_status, Disabled);
1268 if (rs == Recording) {
1269 g_atomic_int_set (&_record_status, Enabled);
1273 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
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 (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
1283 if ((*i)->record_enabled ()) {
1284 (*i)->monitor_input (false);
1289 RecordStateChanged (); /* emit signal */
1292 remove_pending_capture_state ();
1298 Session::step_back_from_record ()
1300 g_atomic_int_set (&_record_status, Enabled);
1302 if (Config->get_use_hardware_monitoring()) {
1303 /* Even though this can be called from RT context we are using
1304 a non-tentative rwlock here, because the action must occur.
1305 The rarity and short potential lock duration makes this "OK"
1307 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1309 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
1310 if (auto_input && (*i)->record_enabled ()) {
1311 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1312 (*i)->monitor_input (false);
1319 Session::maybe_enable_record ()
1321 g_atomic_int_set (&_record_status, Enabled);
1323 /* XXX this save should really happen in another thread. its needed so that
1324 pending capture state can be recovered if we crash.
1327 save_state ("", true);
1329 if (_transport_speed) {
1334 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1335 RecordStateChanged (); /* EMIT SIGNAL */
1342 Session::audible_frame () const
1345 jack_nframes_t offset;
1348 /* the first of these two possible settings for "offset"
1349 mean that the audible frame is stationary until
1350 audio emerges from the latency compensation
1353 the second means that the audible frame is stationary
1354 until audio would emerge from a physical port
1355 in the absence of any plugin latency compensation
1358 offset = _worst_output_latency;
1360 if (offset > current_block_size) {
1361 offset -= current_block_size;
1363 /* XXX is this correct? if we have no external
1364 physical connections and everything is internal
1365 then surely this is zero? still, how
1366 likely is that anyway?
1368 offset = current_block_size;
1371 if (synced_to_jack()) {
1372 tf = _engine.transport_frame();
1374 tf = _transport_frame;
1377 if (_transport_speed == 0) {
1387 if (!non_realtime_work_pending()) {
1391 /* take latency into account */
1400 Session::set_frame_rate (jack_nframes_t frames_per_second)
1402 /** \fn void Session::set_frame_size(jack_nframes_t)
1403 the AudioEngine object that calls this guarantees
1404 that it will not be called while we are also in
1405 ::process(). Its fine to do things that block
1409 _current_frame_rate = frames_per_second;
1410 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1412 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1414 // XXX we need some equivalent to this, somehow
1415 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1419 /* XXX need to reset/reinstantiate all LADSPA plugins */
1423 Session::set_block_size (jack_nframes_t nframes)
1425 /* the AudioEngine guarantees
1426 that it will not be called while we are also in
1427 ::process(). It is therefore fine to do things that block
1432 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1433 vector<Sample*>::iterator i;
1436 current_block_size = nframes;
1438 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1442 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1446 _passthru_buffers.clear ();
1447 _silent_buffers.clear ();
1449 ensure_passthru_buffers (np);
1451 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1455 #ifdef NO_POSIX_MEMALIGN
1456 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1458 posix_memalign((void **)&buf,16,current_block_size * 4);
1462 memset (*i, 0, sizeof (Sample) * current_block_size);
1466 if (_gain_automation_buffer) {
1467 delete [] _gain_automation_buffer;
1469 _gain_automation_buffer = new gain_t[nframes];
1471 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1473 boost::shared_ptr<RouteList> r = routes.reader ();
1475 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1476 (*i)->set_block_size (nframes);
1479 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
1480 (*i)->set_block_size (nframes);
1483 set_worst_io_latencies ();
1488 Session::set_default_fade (float steepness, float fade_msecs)
1491 jack_nframes_t fade_frames;
1493 /* Don't allow fade of less 1 frame */
1495 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1502 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1506 default_fade_msecs = fade_msecs;
1507 default_fade_steepness = steepness;
1510 // jlc, WTF is this!
1511 Glib::RWLock::ReaderLock lm (route_lock);
1512 AudioRegion::set_default_fade (steepness, fade_frames);
1517 /* XXX have to do this at some point */
1518 /* foreach region using default fade, reset, then
1519 refill_all_diskstream_buffers ();
1524 struct RouteSorter {
1525 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1526 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1528 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1531 if (r1->fed_by.empty()) {
1532 if (r2->fed_by.empty()) {
1533 /* no ardour-based connections inbound to either route. just use signal order */
1534 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1536 /* r2 has connections, r1 does not; run r1 early */
1540 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1547 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1549 shared_ptr<Route> r2;
1551 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1552 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1556 /* make a copy of the existing list of routes that feed r1 */
1558 set<shared_ptr<Route> > existing = r1->fed_by;
1560 /* for each route that feeds r1, recurse, marking it as feeding
1564 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1567 /* r2 is a route that feeds r1 which somehow feeds base. mark
1568 base as being fed by r2
1571 rbase->fed_by.insert (r2);
1575 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1579 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1583 /* now recurse, so that we can mark base as being fed by
1584 all routes that feed r2
1587 trace_terminal (r2, rbase);
1594 Session::resort_routes ()
1596 /* don't do anything here with signals emitted
1597 by Routes while we are being destroyed.
1600 if (_state_of_the_state & Deletion) {
1607 RCUWriter<RouteList> writer (routes);
1608 shared_ptr<RouteList> r = writer.get_copy ();
1609 resort_routes_using (r);
1610 /* writer goes out of scope and forces update */
1615 Session::resort_routes_using (shared_ptr<RouteList> r)
1617 RouteList::iterator i, j;
1619 for (i = r->begin(); i != r->end(); ++i) {
1621 (*i)->fed_by.clear ();
1623 for (j = r->begin(); j != r->end(); ++j) {
1625 /* although routes can feed themselves, it will
1626 cause an endless recursive descent if we
1627 detect it. so don't bother checking for
1635 if ((*j)->feeds (*i)) {
1636 (*i)->fed_by.insert (*j);
1641 for (i = r->begin(); i != r->end(); ++i) {
1642 trace_terminal (*i, *i);
1649 cerr << "finished route resort\n";
1651 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1652 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1659 shared_ptr<AudioTrack>
1660 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1662 char track_name[32];
1664 uint32_t channels_used = 0;
1666 uint32_t nphysical_in;
1667 uint32_t nphysical_out;
1669 /* count existing audio tracks */
1672 shared_ptr<RouteList> r = routes.reader ();
1674 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1675 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1676 if (!(*i)->hidden()) {
1678 channels_used += (*i)->n_inputs();
1684 /* check for duplicate route names, since we might have pre-existing
1685 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1686 save, close,restart,add new route - first named route is now
1691 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1692 if (route_by_name (track_name) == 0) {
1697 } while (n < (UINT_MAX-1));
1699 if (input_auto_connect & AutoConnectPhysical) {
1700 nphysical_in = n_physical_inputs;
1705 if (output_auto_connect & AutoConnectPhysical) {
1706 nphysical_out = n_physical_outputs;
1712 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1714 if (track->ensure_io (input_channels, output_channels, false, this)) {
1715 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1716 input_channels, output_channels)
1721 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1725 if (input_auto_connect & AutoConnectPhysical) {
1726 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1729 if (port.length() && track->connect_input (track->input (x), port, this)) {
1735 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1739 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1740 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1741 } else if (output_auto_connect & AutoConnectMaster) {
1743 port = _master_out->input (x%_master_out->n_inputs())->name();
1747 if (port.length() && track->connect_output (track->output (x), port, this)) {
1753 vector<string> cports;
1754 uint32_t ni = _control_out->n_inputs();
1756 for (n = 0; n < ni; ++n) {
1757 cports.push_back (_control_out->input(n)->name());
1760 track->set_control_outs (cports);
1763 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes_proxy));
1767 track->set_remote_control_id (ntracks());
1771 catch (failed_constructor &err) {
1772 error << _("Session: could not create new audio track.") << endmsg;
1773 return shared_ptr<AudioTrack> ((AudioTrack*) 0);
1778 Session::new_audio_route (int input_channels, int output_channels)
1784 /* count existing audio busses */
1787 shared_ptr<RouteList> r = routes.reader ();
1789 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1790 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1791 if (!(*i)->hidden()) {
1799 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1800 if (route_by_name (bus_name) == 0) {
1805 } while (n < (UINT_MAX-1));
1808 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1));
1810 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1811 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1812 input_channels, output_channels)
1816 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1820 if (input_auto_connect & AutoConnectPhysical) {
1821 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1824 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1829 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1833 if (output_auto_connect & AutoConnectPhysical) {
1834 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1835 } else if (output_auto_connect & AutoConnectMaster) {
1837 port = _master_out->input (x%_master_out->n_inputs())->name();
1841 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1847 vector<string> cports;
1848 uint32_t ni = _control_out->n_inputs();
1850 for (uint32_t n = 0; n < ni; ++n) {
1851 cports.push_back (_control_out->input(n)->name());
1853 bus->set_control_outs (cports);
1860 catch (failed_constructor &err) {
1861 error << _("Session: could not create new route.") << endmsg;
1862 return shared_ptr<Route> ((Route*) 0);
1867 Session::add_route (shared_ptr<Route> route)
1870 RCUWriter<RouteList> writer (routes);
1871 shared_ptr<RouteList> r = writer.get_copy ();
1872 r->push_front (route);
1873 resort_routes_using (r);
1876 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1877 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1878 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1879 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1881 if (route->master()) {
1882 _master_out = route;
1885 if (route->control()) {
1886 _control_out = route;
1890 save_state (_current_snapshot_name);
1892 RouteAdded (route); /* EMIT SIGNAL */
1896 Session::add_diskstream (AudioDiskstream* dstream)
1898 /* need to do this in case we're rolling at the time, to prevent false underruns */
1899 dstream->do_refill(0, 0, 0);
1902 Glib::RWLock::WriterLock lm (diskstream_lock);
1903 audio_diskstreams.push_back (dstream);
1906 /* take a reference to the diskstream, preventing it from
1907 ever being deleted until the session itself goes away,
1908 or chooses to remove it for its own purposes.
1912 dstream->set_block_size (current_block_size);
1914 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1915 /* this will connect to future changes, and check the current length */
1916 diskstream_playlist_changed (dstream);
1918 dstream->prepare ();
1921 save_state (_current_snapshot_name);
1923 AudioDiskstreamAdded (dstream); /* EMIT SIGNAL */
1927 Session::remove_route (shared_ptr<Route> route)
1930 RCUWriter<RouteList> writer (routes);
1931 shared_ptr<RouteList> rs = writer.get_copy ();
1934 /* deleting the master out seems like a dumb
1935 idea, but its more of a UI policy issue
1939 if (route == _master_out) {
1940 _master_out = shared_ptr<Route> ((Route*) 0);
1943 if (route == _control_out) {
1944 _control_out = shared_ptr<Route> ((Route*) 0);
1946 /* cancel control outs for all routes */
1948 vector<string> empty;
1950 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1951 (*r)->set_control_outs (empty);
1955 update_route_solo_state ();
1957 /* writer goes out of scope, forces route list update */
1961 AudioDiskstream* ds = 0;
1963 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1964 ds = &at->disk_stream();
1970 Glib::RWLock::WriterLock lm (diskstream_lock);
1971 audio_diskstreams.remove (ds);
1977 find_current_end ();
1979 update_latency_compensation (false, false);
1982 /* XXX should we disconnect from the Route's signals ? */
1984 save_state (_current_snapshot_name);
1986 /* all shared ptrs to route should go out of scope here */
1990 Session::route_mute_changed (void* src)
1996 Session::route_solo_changed (void* src, shared_ptr<Route> route)
1998 if (solo_update_disabled) {
2005 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2007 shared_ptr<RouteList> r = routes.reader ();
2009 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2011 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2015 /* don't mess with busses */
2017 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2023 /* don't mess with tracks */
2025 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2030 if ((*i) != route &&
2031 ((*i)->mix_group () == 0 ||
2032 (*i)->mix_group () != route->mix_group () ||
2033 !route->mix_group ()->is_active())) {
2035 if ((*i)->soloed()) {
2037 /* if its already soloed, and solo latching is enabled,
2038 then leave it as it is.
2041 if (_solo_latched) {
2048 solo_update_disabled = true;
2049 (*i)->set_solo (false, src);
2050 solo_update_disabled = false;
2054 bool something_soloed = false;
2055 bool same_thing_soloed = false;
2056 bool signal = false;
2058 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2059 if ((*i)->soloed()) {
2060 something_soloed = true;
2061 if (dynamic_cast<AudioTrack*>((*i).get())) {
2063 same_thing_soloed = true;
2068 same_thing_soloed = true;
2076 if (something_soloed != currently_soloing) {
2078 currently_soloing = something_soloed;
2081 modify_solo_mute (is_track, same_thing_soloed);
2084 SoloActive (currently_soloing);
2091 Session::set_solo_latched (bool yn)
2093 if (yn != _solo_latched) {
2096 ControlChanged (SoloLatch);
2101 Session::update_route_solo_state ()
2104 bool is_track = false;
2105 bool signal = false;
2107 /* caller must hold RouteLock */
2109 /* this is where we actually implement solo by changing
2110 the solo mute setting of each track.
2113 shared_ptr<RouteList> r = routes.reader ();
2115 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2116 if ((*i)->soloed()) {
2118 if (dynamic_cast<AudioTrack*>((*i).get())) {
2125 if (mute != currently_soloing) {
2127 currently_soloing = mute;
2130 if (!is_track && !mute) {
2132 /* nothing is soloed */
2134 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2135 (*i)->set_solo_mute (false);
2145 modify_solo_mute (is_track, mute);
2148 SoloActive (currently_soloing);
2153 Session::modify_solo_mute (bool is_track, bool mute)
2155 shared_ptr<RouteList> r = routes.reader ();
2157 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2161 /* only alter track solo mute */
2163 if (dynamic_cast<AudioTrack*>((*i).get())) {
2164 if ((*i)->soloed()) {
2165 (*i)->set_solo_mute (!mute);
2167 (*i)->set_solo_mute (mute);
2173 /* only alter bus solo mute */
2175 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2177 if ((*i)->soloed()) {
2179 (*i)->set_solo_mute (false);
2183 /* don't mute master or control outs
2184 in response to another bus solo
2187 if ((*i) != _master_out &&
2188 (*i) != _control_out) {
2189 (*i)->set_solo_mute (mute);
2200 Session::catch_up_on_solo ()
2202 /* this is called after set_state() to catch the full solo
2203 state, which can't be correctly determined on a per-route
2204 basis, but needs the global overview that only the session
2207 update_route_solo_state();
2211 Session::route_by_name (string name)
2213 shared_ptr<RouteList> r = routes.reader ();
2215 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2216 if ((*i)->name() == name) {
2221 return shared_ptr<Route> ((Route*) 0);
2225 Session::route_by_remote_id (uint32_t id)
2227 shared_ptr<RouteList> r = routes.reader ();
2229 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2230 if ((*i)->remote_control_id() == id) {
2235 return shared_ptr<Route> ((Route*) 0);
2239 Session::find_current_end ()
2241 if (_state_of_the_state & Loading) {
2245 jack_nframes_t max = get_maximum_extent ();
2247 if (max > end_location->end()) {
2248 end_location->set_end (max);
2250 DurationChanged(); /* EMIT SIGNAL */
2255 Session::get_maximum_extent () const
2257 jack_nframes_t max = 0;
2260 /* Don't take the diskstream lock. Caller must have other ways to
2264 for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2265 Playlist* pl = (*i)->playlist();
2266 if ((me = pl->get_maximum_extent()) > max) {
2275 Session::diskstream_by_name (string name)
2277 Glib::RWLock::ReaderLock lm (diskstream_lock);
2279 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2280 if ((*i)->name() == name) {
2289 Session::diskstream_by_id (const PBD::ID& id)
2291 Glib::RWLock::ReaderLock lm (diskstream_lock);
2293 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2294 if ((*i)->id() == id) {
2302 /* AudioRegion management */
2305 Session::new_region_name (string old)
2307 string::size_type last_period;
2309 string::size_type len = old.length() + 64;
2312 if ((last_period = old.find_last_of ('.')) == string::npos) {
2314 /* no period present - add one explicitly */
2317 last_period = old.length() - 1;
2322 number = atoi (old.substr (last_period+1).c_str());
2326 while (number < (UINT_MAX-1)) {
2328 AudioRegionList::const_iterator i;
2333 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2336 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2337 if (i->second->name() == sbuf) {
2342 if (i == audio_regions.end()) {
2347 if (number != (UINT_MAX-1)) {
2351 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2356 Session::region_name (string& result, string base, bool newlevel) const
2363 Glib::Mutex::Lock lm (region_lock);
2365 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2373 /* XXX this is going to be slow. optimize me later */
2378 string::size_type pos;
2380 pos = base.find_last_of ('.');
2382 /* pos may be npos, but then we just use entire base */
2384 subbase = base.substr (0, pos);
2388 bool name_taken = true;
2391 Glib::Mutex::Lock lm (region_lock);
2393 for (int n = 1; n < 5000; ++n) {
2396 snprintf (buf, sizeof (buf), ".%d", n);
2401 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2402 if (i->second->name() == result) {
2415 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2423 Session::add_region (Region* region)
2425 AudioRegion* ar = 0;
2426 AudioRegion* oar = 0;
2430 Glib::Mutex::Lock lm (region_lock);
2432 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2434 AudioRegionList::iterator x;
2436 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2438 oar = dynamic_cast<AudioRegion*> (x->second);
2440 if (ar->region_list_equivalent (*oar)) {
2445 if (x == audio_regions.end()) {
2447 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2449 entry.first = region->id();
2452 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2463 fatal << _("programming error: ")
2464 << X_("unknown region type passed to Session::add_region()")
2471 /* mark dirty because something has changed even if we didn't
2472 add the region to the region list.
2478 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2479 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2480 AudioRegionAdded (ar); /* EMIT SIGNAL */
2485 Session::region_changed (Change what_changed, Region* region)
2487 if (what_changed & Region::HiddenChanged) {
2488 /* relay hidden changes */
2489 RegionHiddenChange (region);
2494 Session::region_renamed (Region* region)
2496 add_region (region);
2500 Session::remove_region (Region* region)
2502 AudioRegionList::iterator i;
2503 AudioRegion* ar = 0;
2504 bool removed = false;
2507 Glib::Mutex::Lock lm (region_lock);
2509 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2510 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2511 audio_regions.erase (i);
2517 fatal << _("programming error: ")
2518 << X_("unknown region type passed to Session::remove_region()")
2524 /* mark dirty because something has changed even if we didn't
2525 remove the region from the region list.
2531 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2536 Session::find_whole_file_parent (AudioRegion& child)
2538 AudioRegionList::iterator i;
2539 AudioRegion* region;
2540 Glib::Mutex::Lock lm (region_lock);
2542 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2546 if (region->whole_file()) {
2548 if (child.source_equivalent (*region)) {
2558 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2560 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2564 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2568 pl->get_region_list_equivalent_regions (region, result);
2573 Session::destroy_region (Region* region)
2575 AudioRegion* aregion;
2577 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2581 if (aregion->playlist()) {
2582 aregion->playlist()->destroy_region (region);
2585 vector<Source*> srcs;
2587 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2588 srcs.push_back (&aregion->source (n));
2591 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2593 if ((*i)->use_cnt() == 0) {
2594 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2596 (afs)->mark_for_remove ();
2606 Session::destroy_regions (list<Region*> regions)
2608 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2609 destroy_region (*i);
2615 Session::remove_last_capture ()
2619 Glib::RWLock::ReaderLock lm (diskstream_lock);
2621 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2622 list<Region*>& l = (*i)->last_capture_regions();
2625 r.insert (r.end(), l.begin(), l.end());
2630 destroy_regions (r);
2635 Session::remove_region_from_region_list (Region& r)
2641 /* Source Management */
2644 Session::add_audio_source (AudioSource* source)
2646 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2649 Glib::Mutex::Lock lm (audio_source_lock);
2650 entry.first = source->id();
2651 entry.second = source;
2652 audio_sources.insert (entry);
2655 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2658 SourceAdded (source); /* EMIT SIGNAL */
2662 Session::remove_source (Source* source)
2664 AudioSourceList::iterator i;
2667 Glib::Mutex::Lock lm (audio_source_lock);
2669 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2670 audio_sources.erase (i);
2674 if (!_state_of_the_state & InCleanup) {
2676 /* save state so we don't end up with a session file
2677 referring to non-existent sources.
2680 save_state (_current_snapshot_name);
2683 SourceRemoved(source); /* EMIT SIGNAL */
2687 Session::source_by_id (const PBD::ID& id)
2689 Glib::Mutex::Lock lm (audio_source_lock);
2690 AudioSourceList::iterator i;
2693 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2697 /* XXX search MIDI or other searches here */
2703 Session::peak_path_from_audio_path (string audio_path)
2705 /* XXX hardly bombproof! fix me */
2709 res = Glib::path_get_dirname (audio_path);
2710 res = Glib::path_get_dirname (res);
2712 res += peak_dir_name;
2714 res += PBD::basename_nosuffix (audio_path);
2721 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2724 string old_basename = PBD::basename_nosuffix (oldname);
2725 string new_legalized = legalize_for_path (newname);
2727 /* note: we know (or assume) the old path is already valid */
2731 /* destructive file sources have a name of the form:
2733 /path/to/Tnnnn-NAME(%[LR])?.wav
2735 the task here is to replace NAME with the new name.
2738 /* find last slash */
2742 string::size_type slash;
2743 string::size_type dash;
2745 if ((slash = path.find_last_of ('/')) == string::npos) {
2749 dir = path.substr (0, slash+1);
2751 /* '-' is not a legal character for the NAME part of the path */
2753 if ((dash = path.find_last_of ('-')) == string::npos) {
2757 prefix = path.substr (slash+1, dash-(slash+1));
2762 path += new_legalized;
2763 path += ".wav"; /* XXX gag me with a spoon */
2767 /* non-destructive file sources have a name of the form:
2769 /path/to/NAME-nnnnn(%[LR])?.wav
2771 the task here is to replace NAME with the new name.
2774 /* find last slash */
2778 string::size_type slash;
2779 string::size_type dash;
2781 if ((slash = path.find_last_of ('/')) == string::npos) {
2785 dir = path.substr (0, slash+1);
2787 /* '-' is not a legal character for the NAME part of the path */
2789 if ((dash = path.find_last_of ('-')) == string::npos) {
2793 suffix = path.substr (dash);
2796 path += new_legalized;
2804 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2808 char buf[PATH_MAX+1];
2809 const uint32_t limit = 10000;
2813 legalized = legalize_for_path (name);
2815 /* find a "version" of the file name that doesn't exist in
2816 any of the possible directories.
2819 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2821 vector<space_and_path>::iterator i;
2822 uint32_t existing = 0;
2824 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2829 spath += tape_dir_name;
2831 spath += sound_dir_name;
2836 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2837 } else if (nchan == 2) {
2839 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2841 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2843 } else if (nchan < 26) {
2844 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2846 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2854 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2855 } else if (nchan == 2) {
2857 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2859 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2861 } else if (nchan < 26) {
2862 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2864 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2868 if (access (buf, F_OK) == 0) {
2873 if (existing == 0) {
2878 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2879 throw failed_constructor();
2883 /* we now have a unique name for the file, but figure out where to
2890 spath = tape_dir ();
2892 spath = discover_best_sound_dir ();
2895 string::size_type pos = foo.find_last_of ('/');
2897 if (pos == string::npos) {
2900 spath += foo.substr (pos + 1);
2907 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2909 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2911 /* this might throw failed_constructor(), which is OK */
2914 return new DestructiveFileSource (spath,
2915 Config->get_native_file_data_format(),
2916 Config->get_native_file_header_format(),
2919 return new SndFileSource (spath,
2920 Config->get_native_file_data_format(),
2921 Config->get_native_file_header_format(),
2926 /* Playlist management */
2929 Session::get_playlist (string name)
2933 if ((ret = playlist_by_name (name)) == 0) {
2934 ret = new AudioPlaylist (*this, name);
2941 Session::playlist_by_name (string name)
2943 Glib::Mutex::Lock lm (playlist_lock);
2944 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2945 if ((*i)->name() == name) {
2949 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2950 if ((*i)->name() == name) {
2958 Session::add_playlist (Playlist* playlist)
2960 if (playlist->hidden()) {
2965 Glib::Mutex::Lock lm (playlist_lock);
2966 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2967 playlists.insert (playlists.begin(), playlist);
2969 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2970 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2976 PlaylistAdded (playlist); /* EMIT SIGNAL */
2980 Session::track_playlist (Playlist* pl, bool inuse)
2982 PlaylistList::iterator x;
2985 Glib::Mutex::Lock lm (playlist_lock);
2988 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2990 unused_playlists.insert (pl);
2992 if ((x = playlists.find (pl)) != playlists.end()) {
2993 playlists.erase (x);
2998 //cerr << "shifting playlist to used: " << pl->name() << endl;
3000 playlists.insert (pl);
3002 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3003 unused_playlists.erase (x);
3010 Session::remove_playlist (Playlist* playlist)
3012 if (_state_of_the_state & Deletion) {
3017 Glib::Mutex::Lock lm (playlist_lock);
3018 // cerr << "removing playlist: " << playlist->name() << endl;
3020 PlaylistList::iterator i;
3022 i = find (playlists.begin(), playlists.end(), playlist);
3024 if (i != playlists.end()) {
3025 playlists.erase (i);
3028 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3029 if (i != unused_playlists.end()) {
3030 unused_playlists.erase (i);
3037 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3041 Session::set_audition (AudioRegion* r)
3043 pending_audition_region = r;
3044 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3045 schedule_butler_transport_work ();
3049 Session::non_realtime_set_audition ()
3051 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3052 auditioner->audition_current_playlist ();
3053 } else if (pending_audition_region) {
3054 auditioner->audition_region (*pending_audition_region);
3056 pending_audition_region = 0;
3057 AuditionActive (true); /* EMIT SIGNAL */
3061 Session::audition_playlist ()
3063 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3064 ev->set_ptr ((void*) 0xfeedface);
3069 Session::audition_region (AudioRegion& r)
3071 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3077 Session::cancel_audition ()
3079 if (auditioner->active()) {
3080 auditioner->cancel_audition ();
3081 AuditionActive (false); /* EMIT SIGNAL */
3086 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3088 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3092 Session::remove_empty_sounds ()
3095 PathScanner scanner;
3100 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3102 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3104 if (AudioFileSource::is_empty (*(*i))) {
3106 unlink ((*i)->c_str());
3108 string peak_path = peak_path_from_audio_path (**i);
3109 unlink (peak_path.c_str());
3115 delete possible_audiofiles;
3119 Session::is_auditioning () const
3121 /* can be called before we have an auditioner object */
3123 return auditioner->active();
3130 Session::set_all_solo (bool yn)
3132 shared_ptr<RouteList> r = routes.reader ();
3134 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3135 if (!(*i)->hidden()) {
3136 (*i)->set_solo (yn, this);
3144 Session::set_all_mute (bool yn)
3146 shared_ptr<RouteList> r = routes.reader ();
3148 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3149 if (!(*i)->hidden()) {
3150 (*i)->set_mute (yn, this);
3158 Session::n_audio_diskstreams () const
3160 Glib::RWLock::ReaderLock lm (diskstream_lock);
3163 for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3164 if (!(*i)->hidden()) {
3172 Session::foreach_audio_diskstream (void (AudioDiskstream::*func)(void))
3174 Glib::RWLock::ReaderLock lm (diskstream_lock);
3175 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3176 if (!(*i)->hidden()) {
3183 Session::graph_reordered ()
3185 /* don't do this stuff if we are setting up connections
3186 from a set_state() call.
3189 if (_state_of_the_state & InitialConnecting) {
3193 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3197 /* force all diskstreams to update their capture offset values to
3198 reflect any changes in latencies within the graph.
3201 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3202 (*i)->set_capture_offset ();
3207 Session::record_disenable_all ()
3209 record_enable_change_all (false);
3213 Session::record_enable_all ()
3215 record_enable_change_all (true);
3219 Session::record_enable_change_all (bool yn)
3221 shared_ptr<RouteList> r = routes.reader ();
3223 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3226 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3227 at->set_record_enable (yn, this);
3231 /* since we don't keep rec-enable state, don't mark session dirty */
3235 Session::add_redirect (Redirect* redirect)
3239 PortInsert* port_insert;
3240 PluginInsert* plugin_insert;
3242 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3243 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3244 _port_inserts.insert (_port_inserts.begin(), port_insert);
3245 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3246 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3248 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3251 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3252 _sends.insert (_sends.begin(), send);
3254 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3258 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3264 Session::remove_redirect (Redirect* redirect)
3268 PortInsert* port_insert;
3269 PluginInsert* plugin_insert;
3271 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3272 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3273 _port_inserts.remove (port_insert);
3274 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3275 _plugin_inserts.remove (plugin_insert);
3277 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3280 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3281 _sends.remove (send);
3283 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3291 Session::available_capture_duration ()
3293 const double scale = 4096.0 / sizeof (Sample);
3295 if (_total_free_4k_blocks * scale > (double) max_frames) {
3299 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3303 Session::add_connection (ARDOUR::Connection* connection)
3306 Glib::Mutex::Lock guard (connection_lock);
3307 _connections.push_back (connection);
3310 ConnectionAdded (connection); /* EMIT SIGNAL */
3316 Session::remove_connection (ARDOUR::Connection* connection)
3318 bool removed = false;
3321 Glib::Mutex::Lock guard (connection_lock);
3322 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3324 if (i != _connections.end()) {
3325 _connections.erase (i);
3331 ConnectionRemoved (connection); /* EMIT SIGNAL */
3337 ARDOUR::Connection *
3338 Session::connection_by_name (string name) const
3340 Glib::Mutex::Lock lm (connection_lock);
3342 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3343 if ((*i)->name() == name) {
3352 Session::set_edit_mode (EditMode mode)
3357 Glib::Mutex::Lock lm (playlist_lock);
3359 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3360 (*i)->set_edit_mode (mode);
3365 ControlChanged (EditingMode); /* EMIT SIGNAL */
3369 Session::tempo_map_changed (Change ignored)
3376 Session::ensure_passthru_buffers (uint32_t howmany)
3378 while (howmany > _passthru_buffers.size()) {
3380 #ifdef NO_POSIX_MEMALIGN
3381 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3383 posix_memalign((void **)&p,16,current_block_size * 4);
3385 _passthru_buffers.push_back (p);
3389 #ifdef NO_POSIX_MEMALIGN
3390 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3392 posix_memalign((void **)&p,16,current_block_size * 4);
3394 memset (p, 0, sizeof (Sample) * current_block_size);
3395 _silent_buffers.push_back (p);
3399 #ifdef NO_POSIX_MEMALIGN
3400 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3402 posix_memalign((void **)&p,16,current_block_size * 4);
3404 memset (p, 0, sizeof (Sample) * current_block_size);
3405 _send_buffers.push_back (p);
3408 allocate_pan_automation_buffers (current_block_size, howmany, false);
3412 Session::next_send_name ()
3415 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3420 Session::next_insert_name ()
3423 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3427 /* Named Selection management */
3430 Session::named_selection_by_name (string name)
3432 Glib::Mutex::Lock lm (named_selection_lock);
3433 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3434 if ((*i)->name == name) {
3442 Session::add_named_selection (NamedSelection* named_selection)
3445 Glib::Mutex::Lock lm (named_selection_lock);
3446 named_selections.insert (named_selections.begin(), named_selection);
3451 NamedSelectionAdded (); /* EMIT SIGNAL */
3455 Session::remove_named_selection (NamedSelection* named_selection)
3457 bool removed = false;
3460 Glib::Mutex::Lock lm (named_selection_lock);
3462 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3464 if (i != named_selections.end()) {
3466 named_selections.erase (i);
3473 NamedSelectionRemoved (); /* EMIT SIGNAL */
3478 Session::reset_native_file_format ()
3480 // jlc - WHY take routelock?
3481 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3482 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3484 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3485 (*i)->reset_write_sources (false);
3490 Session::route_name_unique (string n) const
3492 shared_ptr<RouteList> r = routes.reader ();
3494 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3495 if ((*i)->name() == n) {
3504 Session::cleanup_audio_file_source (AudioFileSource& fs)
3506 return fs.move_to_trash (dead_sound_dir_name);
3510 Session::n_playlists () const
3512 Glib::Mutex::Lock lm (playlist_lock);
3513 return playlists.size();
3517 Session::set_solo_model (SoloModel sm)
3519 if (sm != _solo_model) {
3521 ControlChanged (SoloingModel);
3527 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3529 if (!force && howmany <= _npan_buffers) {
3533 if (_pan_automation_buffer) {
3535 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3536 delete [] _pan_automation_buffer[i];
3539 delete [] _pan_automation_buffer;
3542 _pan_automation_buffer = new pan_t*[howmany];
3544 for (uint32_t i = 0; i < howmany; ++i) {
3545 _pan_automation_buffer[i] = new pan_t[nframes];
3548 _npan_buffers = howmany;
3552 Session::freeze (InterThreadInfo& itt)
3554 shared_ptr<RouteList> r = routes.reader ();
3556 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3560 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3561 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3572 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3573 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3577 AudioFileSource* fsource;
3579 char buf[PATH_MAX+1];
3582 jack_nframes_t position;
3583 jack_nframes_t this_chunk;
3584 jack_nframes_t to_do;
3585 vector<Sample*> buffers;
3588 // any bigger than this seems to cause stack overflows in called functions
3589 const jack_nframes_t chunk_size = (128 * 1024)/4;
3591 g_atomic_int_set (&processing_prohibited, 1);
3593 /* call tree *MUST* hold route_lock */
3595 if ((playlist = track.disk_stream().playlist()) == 0) {
3599 /* external redirects will be a problem */
3601 if (track.has_external_redirects()) {
3605 nchans = track.disk_stream().n_channels();
3607 dir = discover_best_sound_dir ();
3609 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3611 for (x = 0; x < 99999; ++x) {
3612 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3613 if (access (buf, F_OK) != 0) {
3619 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3624 fsource = new SndFileSource (buf,
3625 Config->get_native_file_data_format(),
3626 Config->get_native_file_header_format(),
3631 catch (failed_constructor& err) {
3632 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3636 srcs.push_back(fsource);
3639 /* XXX need to flush all redirects */
3644 /* create a set of reasonably-sized buffers */
3646 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3648 #ifdef NO_POSIX_MEMALIGN
3649 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3651 posix_memalign((void **)&b,16,chunk_size * 4);
3653 buffers.push_back (b);
3656 workbuf = new char[chunk_size * 4];
3658 while (to_do && !itt.cancel) {
3660 this_chunk = min (to_do, chunk_size);
3662 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3667 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3668 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3671 if (afs->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3677 start += this_chunk;
3678 to_do -= this_chunk;
3680 itt.progress = (float) (1.0 - ((double) to_do / len));
3689 xnow = localtime (&now);
3691 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3692 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3694 afs->update_header (position, *xnow, now);
3698 /* build peakfile for new source */
3700 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3701 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3703 afs->build_peaks ();
3712 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3713 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3715 afs->mark_for_remove ();
3721 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3729 g_atomic_int_set (&processing_prohibited, 0);
3737 Session::get_silent_buffers (uint32_t howmany)
3739 for (uint32_t i = 0; i < howmany; ++i) {
3740 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3742 return _silent_buffers;
3746 Session::ntracks () const
3749 shared_ptr<RouteList> r = routes.reader ();
3751 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3752 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3761 Session::nbusses () const
3764 shared_ptr<RouteList> r = routes.reader ();
3766 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3767 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3776 Session::set_layer_model (LayerModel lm)
3778 if (lm != layer_model) {
3781 ControlChanged (LayeringModel);
3786 Session::set_xfade_model (CrossfadeModel xm)
3788 if (xm != xfade_model) {
3791 ControlChanged (CrossfadingModel);