2 Copyright (C) 1999-2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <cstdio> /* sprintf(3) ... grrr */
32 #include <sigc++/bind.h>
33 #include <sigc++/retype.h>
35 #include <glibmm/thread.h>
36 #include <glibmm/miscutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/audio_diskstream.h>
48 #include <ardour/utils.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/destructive_filesource.h>
53 #include <ardour/auditioner.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/redirect.h>
56 #include <ardour/send.h>
57 #include <ardour/insert.h>
58 #include <ardour/connection.h>
59 #include <ardour/slave.h>
60 #include <ardour/tempo.h>
61 #include <ardour/audio_track.h>
62 #include <ardour/cycle_timer.h>
63 #include <ardour/named_selection.h>
64 #include <ardour/crossfade.h>
65 #include <ardour/playlist.h>
66 #include <ardour/click.h>
67 #include <ardour/data_type.h>
70 #include <ardour/osc.h>
76 using namespace ARDOUR;
78 using boost::shared_ptr;
80 const char* Session::_template_suffix = X_(".template");
81 const char* Session::_statefile_suffix = X_(".ardour");
82 const char* Session::_pending_suffix = X_(".pending");
83 const char* Session::sound_dir_name = X_("sounds");
84 const char* Session::tape_dir_name = X_("tapes");
85 const char* Session::peak_dir_name = X_("peaks");
86 const char* Session::dead_sound_dir_name = X_("dead_sounds");
88 Session::compute_peak_t Session::compute_peak = 0;
89 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
90 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
91 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
93 sigc::signal<int> Session::AskAboutPendingState;
94 sigc::signal<void> Session::SMPTEOffsetChanged;
95 sigc::signal<void> Session::SendFeedback;
99 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
102 char buf[PATH_MAX+1];
106 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
107 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
113 /* check to see if it exists, and what it is */
115 if (stat (str.c_str(), &statbuf)) {
116 if (errno == ENOENT) {
119 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
127 /* it exists, so it must either be the name
128 of the directory, or the name of the statefile
132 if (S_ISDIR (statbuf.st_mode)) {
134 string::size_type slash = str.find_last_of ('/');
136 if (slash == string::npos) {
138 /* a subdirectory of cwd, so statefile should be ... */
144 tmp += _statefile_suffix;
148 if (stat (tmp.c_str(), &statbuf)) {
149 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
159 /* some directory someplace in the filesystem.
160 the snapshot name is the directory name
165 snapshot = str.substr (slash+1);
169 } else if (S_ISREG (statbuf.st_mode)) {
171 string::size_type slash = str.find_last_of ('/');
172 string::size_type suffix;
174 /* remove the suffix */
176 if (slash != string::npos) {
177 snapshot = str.substr (slash+1);
182 suffix = snapshot.find (_statefile_suffix);
184 if (suffix == string::npos) {
185 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
191 snapshot = snapshot.substr (0, suffix);
193 if (slash == string::npos) {
195 /* we must be in the directory where the
196 statefile lives. get it using cwd().
199 char cwd[PATH_MAX+1];
201 if (getcwd (cwd, sizeof (cwd)) == 0) {
202 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
211 /* full path to the statefile */
213 path = str.substr (0, slash);
218 /* what type of file is it? */
219 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
225 /* its the name of a new directory. get the name
229 string::size_type slash = str.find_last_of ('/');
231 if (slash == string::npos) {
233 /* no slash, just use the name, but clean it up */
235 path = legalize_for_path (str);
241 snapshot = str.substr (slash+1);
248 Session::Session (AudioEngine &eng,
250 string snapshot_name,
251 string* mix_template)
254 _mmc_port (default_mmc_port),
255 _mtc_port (default_mtc_port),
256 _midi_port (default_midi_port),
257 pending_events (2048),
258 midi_requests (128), // the size of this should match the midi request pool size
259 routes (new RouteList),
260 auditioner ((Auditioner*) 0),
266 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
268 n_physical_outputs = _engine.n_physical_outputs();
269 n_physical_inputs = _engine.n_physical_inputs();
271 first_stage_init (fullpath, snapshot_name);
273 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
274 throw failed_constructor ();
277 if (second_stage_init (new_session)) {
278 throw failed_constructor ();
281 store_recent_sessions(_name, _path);
283 bool was_dirty = dirty();
285 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
288 DirtyChanged (); /* EMIT SIGNAL */
292 Session::Session (AudioEngine &eng,
294 string snapshot_name,
295 AutoConnectOption input_ac,
296 AutoConnectOption output_ac,
297 uint32_t control_out_channels,
298 uint32_t master_out_channels,
299 uint32_t requested_physical_in,
300 uint32_t requested_physical_out,
301 jack_nframes_t initial_length)
304 _mmc_port (default_mmc_port),
305 _mtc_port (default_mtc_port),
306 _midi_port (default_midi_port),
307 pending_events (2048),
309 routes (new RouteList),
315 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
317 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
318 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
320 first_stage_init (fullpath, snapshot_name);
322 if (create (new_session, 0, initial_length)) {
323 throw failed_constructor ();
326 if (control_out_channels) {
327 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
332 if (master_out_channels) {
333 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
337 /* prohibit auto-connect to master, because there isn't one */
338 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
341 input_auto_connect = input_ac;
342 output_auto_connect = output_ac;
344 if (second_stage_init (new_session)) {
345 throw failed_constructor ();
348 store_recent_sessions(_name, _path);
350 bool was_dirty = dirty ();
352 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
355 DirtyChanged (); /* EMIT SIGNAL */
361 /* if we got to here, leaving pending capture state around
365 remove_pending_capture_state ();
367 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
368 _engine.remove_session ();
370 going_away (); /* EMIT SIGNAL */
372 terminate_butler_thread ();
373 terminate_midi_thread ();
375 if (click_data && click_data != default_click) {
376 delete [] click_data;
379 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
380 delete [] click_emphasis_data;
385 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
389 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
393 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
397 AudioDiskstream::free_working_buffers();
399 #undef TRACK_DESTRUCTION
400 #ifdef TRACK_DESTRUCTION
401 cerr << "delete named selections\n";
402 #endif /* TRACK_DESTRUCTION */
403 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
404 NamedSelectionList::iterator tmp;
413 #ifdef TRACK_DESTRUCTION
414 cerr << "delete playlists\n";
415 #endif /* TRACK_DESTRUCTION */
416 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
417 PlaylistList::iterator tmp;
427 #ifdef TRACK_DESTRUCTION
428 cerr << "delete audio regions\n";
429 #endif /* TRACK_DESTRUCTION */
430 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
431 AudioRegionList::iterator tmp;
441 #ifdef TRACK_DESTRUCTION
442 cerr << "delete diskstreams\n";
443 #endif /* TRACK_DESTRUCTION */
444 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
445 DiskstreamList::iterator tmp;
455 #ifdef TRACK_DESTRUCTION
456 cerr << "delete audio sources\n";
457 #endif /* TRACK_DESTRUCTION */
458 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
459 AudioSourceList::iterator tmp;
469 #ifdef TRACK_DESTRUCTION
470 cerr << "delete mix groups\n";
471 #endif /* TRACK_DESTRUCTION */
472 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
473 list<RouteGroup*>::iterator tmp;
483 #ifdef TRACK_DESTRUCTION
484 cerr << "delete edit groups\n";
485 #endif /* TRACK_DESTRUCTION */
486 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
487 list<RouteGroup*>::iterator tmp;
497 #ifdef TRACK_DESTRUCTION
498 cerr << "delete connections\n";
499 #endif /* TRACK_DESTRUCTION */
500 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
501 ConnectionList::iterator tmp;
511 if (butler_mixdown_buffer) {
512 delete [] butler_mixdown_buffer;
515 if (butler_gain_buffer) {
516 delete [] butler_gain_buffer;
519 Crossfade::set_buffer_size (0);
531 Session::set_worst_io_latencies ()
533 _worst_output_latency = 0;
534 _worst_input_latency = 0;
536 if (!_engine.connected()) {
540 boost::shared_ptr<RouteList> r = routes.reader ();
542 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
543 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
544 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
549 Session::when_engine_running ()
551 string first_physical_output;
553 /* we don't want to run execute this again */
555 first_time_running.disconnect ();
557 set_block_size (_engine.frames_per_cycle());
558 set_frame_rate (_engine.frame_rate());
560 /* every time we reconnect, recompute worst case output latencies */
562 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
564 if (synced_to_jack()) {
565 _engine.transport_stop ();
568 if (Config->get_jack_time_master()) {
569 _engine.transport_locate (_transport_frame);
577 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
579 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
581 /* existing state for Click */
583 if (_click_io->set_state (*child->children().front()) == 0) {
585 _clicking = click_requested;
589 error << _("could not setup Click I/O") << endmsg;
595 /* default state for Click */
597 first_physical_output = _engine.get_nth_physical_output (0);
599 if (first_physical_output.length()) {
600 if (_click_io->add_output_port (first_physical_output, this)) {
601 // relax, even though its an error
603 _clicking = click_requested;
609 catch (failed_constructor& err) {
610 error << _("cannot setup Click I/O") << endmsg;
613 set_worst_io_latencies ();
616 ControlChanged (Clicking); /* EMIT SIGNAL */
619 if (auditioner == 0) {
621 /* we delay creating the auditioner till now because
622 it makes its own connections to ports named
623 in the ARDOUR_RC config file. the engine has
624 to be running for this to work.
628 auditioner.reset (new Auditioner (*this));
631 catch (failed_constructor& err) {
632 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
636 /* Create a set of Connection objects that map
637 to the physical outputs currently available
642 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
644 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
646 Connection* c = new OutputConnection (buf, true);
649 c->add_connection (0, _engine.get_nth_physical_output (np));
654 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
656 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
658 Connection* c = new InputConnection (buf, true);
661 c->add_connection (0, _engine.get_nth_physical_input (np));
668 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
670 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
672 Connection* c = new OutputConnection (buf, true);
676 c->add_connection (0, _engine.get_nth_physical_output (np));
677 c->add_connection (1, _engine.get_nth_physical_output (np+1));
682 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
684 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
686 Connection* c = new InputConnection (buf, true);
690 c->add_connection (0, _engine.get_nth_physical_input (np));
691 c->add_connection (1, _engine.get_nth_physical_input (np+1));
700 /* create master/control ports */
705 /* force the master to ignore any later call to this */
707 if (_master_out->pending_state_node) {
708 _master_out->ports_became_legal();
711 /* no panner resets till we are through */
713 _master_out->defer_pan_reset ();
715 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
716 if (_master_out->add_input_port ("", this)) {
717 error << _("cannot setup master inputs")
723 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
724 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
725 error << _("cannot setup master outputs")
732 _master_out->allow_pan_reset ();
736 Connection* c = new OutputConnection (_("Master Out"), true);
738 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
740 c->add_connection ((int) n, _master_out->input(n)->name());
747 /* catch up on send+insert cnts */
751 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
754 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
755 if (id > insert_cnt) {
763 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
766 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
773 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
775 /* hook us up to the engine */
777 _engine.set_session (this);
782 osc->set_session (*this);
785 _state_of_the_state = Clean;
787 DirtyChanged (); /* EMIT SIGNAL */
791 Session::hookup_io ()
793 /* stop graph reordering notifications from
794 causing resorts, etc.
797 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
799 /* Tell all IO objects to create their ports */
806 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
807 if (_control_out->add_input_port ("", this)) {
808 error << _("cannot setup control inputs")
814 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
815 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
816 error << _("cannot set up master outputs")
824 /* Tell all IO objects to connect themselves together */
826 IO::enable_connecting ();
828 /* Now reset all panners */
830 IO::reset_panners ();
832 /* Anyone who cares about input state, wake up and do something */
834 IOConnectionsComplete (); /* EMIT SIGNAL */
836 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
838 /* now handle the whole enchilada as if it was one
844 /* update mixer solo state */
850 Session::playlist_length_changed (Playlist* pl)
852 /* we can't just increase end_location->end() if pl->get_maximum_extent()
853 if larger. if the playlist used to be the longest playlist,
854 and its now shorter, we have to decrease end_location->end(). hence,
855 we have to iterate over all diskstreams and check the
856 playlists currently in use.
862 Session::diskstream_playlist_changed (Diskstream* dstream)
866 if ((playlist = dstream->playlist()) != 0) {
867 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
870 /* see comment in playlist_length_changed () */
875 Session::record_enabling_legal () const
877 /* this used to be in here, but survey says.... we don't need to restrict it */
878 // if (record_status() == Recording) {
889 Session::set_auto_play (bool yn)
891 if (auto_play != yn) {
894 ControlChanged (AutoPlay);
899 Session::set_auto_return (bool yn)
901 if (auto_return != yn) {
904 ControlChanged (AutoReturn);
909 Session::set_crossfades_active (bool yn)
911 if (crossfades_active != yn) {
912 crossfades_active = yn;
914 ControlChanged (CrossFadesActive);
919 Session::set_do_not_record_plugins (bool yn)
921 if (do_not_record_plugins != yn) {
922 do_not_record_plugins = yn;
924 ControlChanged (RecordingPlugins);
929 Session::set_auto_input (bool yn)
931 if (auto_input != yn) {
934 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
935 /* auto-input only makes a difference if we're rolling */
937 /* Even though this can called from RT context we are using
938 a non-tentative rwlock here, because the action must occur.
939 The rarity and short potential lock duration makes this "OK"
941 Glib::RWLock::ReaderLock dsm (diskstream_lock);
942 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
943 if ((*i)->record_enabled ()) {
944 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
945 (*i)->monitor_input (!auto_input);
951 ControlChanged (AutoInput);
956 Session::reset_input_monitor_state ()
958 if (transport_rolling()) {
959 Glib::RWLock::ReaderLock dsm (diskstream_lock);
960 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
961 if ((*i)->record_enabled ()) {
962 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
963 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
967 Glib::RWLock::ReaderLock dsm (diskstream_lock);
968 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
969 if ((*i)->record_enabled ()) {
970 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
971 (*i)->monitor_input (Config->get_use_hardware_monitoring());
979 Session::set_input_auto_connect (bool yn)
982 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
984 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
990 Session::get_input_auto_connect () const
992 return (input_auto_connect & AutoConnectPhysical);
996 Session::set_output_auto_connect (AutoConnectOption aco)
998 output_auto_connect = aco;
1003 Session::auto_punch_start_changed (Location* location)
1005 replace_event (Event::PunchIn, location->start());
1007 if (get_record_enabled() && get_punch_in()) {
1008 /* capture start has been changed, so save new pending state */
1009 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 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 (DiskstreamList::iterator i = diskstreams.begin(); i != 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 (DiskstreamList::iterator i = diskstreams.begin(); i != 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 (DiskstreamList::iterator i = diskstreams.begin(); i != 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);
1330 if (_transport_speed) {
1335 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1336 RecordStateChanged (); /* EMIT SIGNAL */
1343 Session::audible_frame () const
1346 jack_nframes_t offset;
1349 /* the first of these two possible settings for "offset"
1350 mean that the audible frame is stationary until
1351 audio emerges from the latency compensation
1354 the second means that the audible frame is stationary
1355 until audio would emerge from a physical port
1356 in the absence of any plugin latency compensation
1359 offset = _worst_output_latency;
1361 if (offset > current_block_size) {
1362 offset -= current_block_size;
1364 /* XXX is this correct? if we have no external
1365 physical connections and everything is internal
1366 then surely this is zero? still, how
1367 likely is that anyway?
1369 offset = current_block_size;
1372 if (synced_to_jack()) {
1373 tf = _engine.transport_frame();
1375 tf = _transport_frame;
1378 if (_transport_speed == 0) {
1388 if (!non_realtime_work_pending()) {
1392 /* take latency into account */
1401 Session::set_frame_rate (jack_nframes_t frames_per_second)
1403 /** \fn void Session::set_frame_size(jack_nframes_t)
1404 the AudioEngine object that calls this guarantees
1405 that it will not be called while we are also in
1406 ::process(). Its fine to do things that block
1410 _current_frame_rate = frames_per_second;
1411 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1413 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1415 // XXX we need some equivalent to this, somehow
1416 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1420 /* XXX need to reset/reinstantiate all LADSPA plugins */
1424 Session::set_block_size (jack_nframes_t nframes)
1426 /* the AudioEngine guarantees
1427 that it will not be called while we are also in
1428 ::process(). It is therefore fine to do things that block
1433 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1434 vector<Sample*>::iterator i;
1437 current_block_size = nframes;
1439 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1443 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1447 _passthru_buffers.clear ();
1448 _silent_buffers.clear ();
1450 ensure_passthru_buffers (np);
1452 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1456 #ifdef NO_POSIX_MEMALIGN
1457 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1459 posix_memalign((void **)&buf,16,current_block_size * 4);
1463 memset (*i, 0, sizeof (Sample) * current_block_size);
1467 if (_gain_automation_buffer) {
1468 delete [] _gain_automation_buffer;
1470 _gain_automation_buffer = new gain_t[nframes];
1472 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1474 boost::shared_ptr<RouteList> r = routes.reader ();
1476 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1477 (*i)->set_block_size (nframes);
1480 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1481 (*i)->set_block_size (nframes);
1484 set_worst_io_latencies ();
1489 Session::set_default_fade (float steepness, float fade_msecs)
1492 jack_nframes_t fade_frames;
1494 /* Don't allow fade of less 1 frame */
1496 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1503 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1507 default_fade_msecs = fade_msecs;
1508 default_fade_steepness = steepness;
1511 // jlc, WTF is this!
1512 Glib::RWLock::ReaderLock lm (route_lock);
1513 AudioRegion::set_default_fade (steepness, fade_frames);
1518 /* XXX have to do this at some point */
1519 /* foreach region using default fade, reset, then
1520 refill_all_diskstream_buffers ();
1525 struct RouteSorter {
1526 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1527 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1529 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1532 if (r1->fed_by.empty()) {
1533 if (r2->fed_by.empty()) {
1534 /* no ardour-based connections inbound to either route. just use signal order */
1535 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1537 /* r2 has connections, r1 does not; run r1 early */
1541 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1548 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1550 shared_ptr<Route> r2;
1552 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1553 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1557 /* make a copy of the existing list of routes that feed r1 */
1559 set<shared_ptr<Route> > existing = r1->fed_by;
1561 /* for each route that feeds r1, recurse, marking it as feeding
1565 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1568 /* r2 is a route that feeds r1 which somehow feeds base. mark
1569 base as being fed by r2
1572 rbase->fed_by.insert (r2);
1576 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1580 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1584 /* now recurse, so that we can mark base as being fed by
1585 all routes that feed r2
1588 trace_terminal (r2, rbase);
1595 Session::resort_routes ()
1597 /* don't do anything here with signals emitted
1598 by Routes while we are being destroyed.
1601 if (_state_of_the_state & Deletion) {
1608 RCUWriter<RouteList> writer (routes);
1609 shared_ptr<RouteList> r = writer.get_copy ();
1610 resort_routes_using (r);
1611 /* writer goes out of scope and forces update */
1616 Session::resort_routes_using (shared_ptr<RouteList> r)
1618 RouteList::iterator i, j;
1620 for (i = r->begin(); i != r->end(); ++i) {
1622 (*i)->fed_by.clear ();
1624 for (j = r->begin(); j != r->end(); ++j) {
1626 /* although routes can feed themselves, it will
1627 cause an endless recursive descent if we
1628 detect it. so don't bother checking for
1636 if ((*j)->feeds (*i)) {
1637 (*i)->fed_by.insert (*j);
1642 for (i = r->begin(); i != r->end(); ++i) {
1643 trace_terminal (*i, *i);
1650 cerr << "finished route resort\n";
1652 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1653 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1660 shared_ptr<AudioTrack>
1661 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1663 char track_name[32];
1665 uint32_t channels_used = 0;
1667 uint32_t nphysical_in;
1668 uint32_t nphysical_out;
1670 /* count existing audio tracks */
1673 shared_ptr<RouteList> r = routes.reader ();
1675 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1676 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1677 if (!(*i)->hidden()) {
1679 channels_used += (*i)->n_inputs();
1685 /* check for duplicate route names, since we might have pre-existing
1686 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1687 save, close,restart,add new route - first named route is now
1692 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1693 if (route_by_name (track_name) == 0) {
1698 } while (n < (UINT_MAX-1));
1700 if (input_auto_connect & AutoConnectPhysical) {
1701 nphysical_in = n_physical_inputs;
1706 if (output_auto_connect & AutoConnectPhysical) {
1707 nphysical_out = n_physical_outputs;
1713 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1715 if (track->ensure_io (input_channels, output_channels, false, this)) {
1716 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1717 input_channels, output_channels)
1722 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1726 if (input_auto_connect & AutoConnectPhysical) {
1727 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1730 if (port.length() && track->connect_input (track->input (x), port, this)) {
1736 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1740 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1741 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1742 } else if (output_auto_connect & AutoConnectMaster) {
1744 port = _master_out->input (x%_master_out->n_inputs())->name();
1748 if (port.length() && track->connect_output (track->output (x), port, this)) {
1754 vector<string> cports;
1755 uint32_t ni = _control_out->n_inputs();
1757 for (n = 0; n < ni; ++n) {
1758 cports.push_back (_control_out->input(n)->name());
1761 track->set_control_outs (cports);
1764 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1768 track->set_remote_control_id (ntracks());
1772 catch (failed_constructor &err) {
1773 error << _("Session: could not create new audio track.") << endmsg;
1774 return shared_ptr<AudioTrack> ((AudioTrack*) 0);
1779 Session::new_audio_route (int input_channels, int output_channels)
1785 /* count existing audio busses */
1788 shared_ptr<RouteList> r = routes.reader ();
1790 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1791 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1792 if (!(*i)->hidden()) {
1800 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1801 if (route_by_name (bus_name) == 0) {
1806 } while (n < (UINT_MAX-1));
1809 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1811 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1812 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1813 input_channels, output_channels)
1817 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1821 if (input_auto_connect & AutoConnectPhysical) {
1822 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1825 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1830 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1834 if (output_auto_connect & AutoConnectPhysical) {
1835 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1836 } else if (output_auto_connect & AutoConnectMaster) {
1838 port = _master_out->input (x%_master_out->n_inputs())->name();
1842 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1848 vector<string> cports;
1849 uint32_t ni = _control_out->n_inputs();
1851 for (uint32_t n = 0; n < ni; ++n) {
1852 cports.push_back (_control_out->input(n)->name());
1854 bus->set_control_outs (cports);
1861 catch (failed_constructor &err) {
1862 error << _("Session: could not create new audio route.") << endmsg;
1863 return shared_ptr<Route> ((Route*) 0);
1868 Session::add_route (shared_ptr<Route> route)
1871 RCUWriter<RouteList> writer (routes);
1872 shared_ptr<RouteList> r = writer.get_copy ();
1873 r->push_front (route);
1874 resort_routes_using (r);
1877 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1878 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1879 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1880 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1882 if (route->master()) {
1883 _master_out = route;
1886 if (route->control()) {
1887 _control_out = route;
1891 save_state (_current_snapshot_name);
1892 save_history (_current_snapshot_name);
1894 RouteAdded (route); /* EMIT SIGNAL */
1898 Session::add_diskstream (Diskstream* dstream)
1900 /* need to do this in case we're rolling at the time, to prevent false underruns */
1901 dstream->do_refill_with_alloc();
1904 Glib::RWLock::WriterLock lm (diskstream_lock);
1905 diskstreams.push_back (dstream);
1908 /* take a reference to the diskstream, preventing it from
1909 ever being deleted until the session itself goes away,
1910 or chooses to remove it for its own purposes.
1914 dstream->set_block_size (current_block_size);
1916 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1917 /* this will connect to future changes, and check the current length */
1918 diskstream_playlist_changed (dstream);
1920 dstream->prepare ();
1923 save_state (_current_snapshot_name);
1924 save_history (_current_snapshot_name);
1926 DiskstreamAdded (dstream); /* EMIT SIGNAL */
1930 Session::remove_route (shared_ptr<Route> route)
1933 RCUWriter<RouteList> writer (routes);
1934 shared_ptr<RouteList> rs = writer.get_copy ();
1937 /* deleting the master out seems like a dumb
1938 idea, but its more of a UI policy issue
1942 if (route == _master_out) {
1943 _master_out = shared_ptr<Route> ((Route*) 0);
1946 if (route == _control_out) {
1947 _control_out = shared_ptr<Route> ((Route*) 0);
1949 /* cancel control outs for all routes */
1951 vector<string> empty;
1953 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1954 (*r)->set_control_outs (empty);
1958 update_route_solo_state ();
1960 /* writer goes out of scope, forces route list update */
1963 // FIXME: audio specific
1965 AudioDiskstream* ds = 0;
1967 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1968 ds = &at->audio_diskstream();
1974 Glib::RWLock::WriterLock lm (diskstream_lock);
1975 diskstreams.remove (ds);
1981 find_current_end ();
1983 update_latency_compensation (false, false);
1986 /* XXX should we disconnect from the Route's signals ? */
1988 save_state (_current_snapshot_name);
1989 save_history (_current_snapshot_name);
1991 /* all shared ptrs to route should go out of scope here */
1995 Session::route_mute_changed (void* src)
2001 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2003 if (solo_update_disabled) {
2010 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2012 shared_ptr<RouteList> r = routes.reader ();
2014 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2016 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2020 /* don't mess with busses */
2022 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2028 /* don't mess with tracks */
2030 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2035 if ((*i) != route &&
2036 ((*i)->mix_group () == 0 ||
2037 (*i)->mix_group () != route->mix_group () ||
2038 !route->mix_group ()->is_active())) {
2040 if ((*i)->soloed()) {
2042 /* if its already soloed, and solo latching is enabled,
2043 then leave it as it is.
2046 if (_solo_latched) {
2053 solo_update_disabled = true;
2054 (*i)->set_solo (false, src);
2055 solo_update_disabled = false;
2059 bool something_soloed = false;
2060 bool same_thing_soloed = false;
2061 bool signal = false;
2063 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2064 if ((*i)->soloed()) {
2065 something_soloed = true;
2066 if (dynamic_cast<AudioTrack*>((*i).get())) {
2068 same_thing_soloed = true;
2073 same_thing_soloed = true;
2081 if (something_soloed != currently_soloing) {
2083 currently_soloing = something_soloed;
2086 modify_solo_mute (is_track, same_thing_soloed);
2089 SoloActive (currently_soloing);
2096 Session::set_solo_latched (bool yn)
2098 if (yn != _solo_latched) {
2101 ControlChanged (SoloLatch);
2106 Session::update_route_solo_state ()
2109 bool is_track = false;
2110 bool signal = false;
2112 /* caller must hold RouteLock */
2114 /* this is where we actually implement solo by changing
2115 the solo mute setting of each track.
2118 shared_ptr<RouteList> r = routes.reader ();
2120 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2121 if ((*i)->soloed()) {
2123 if (dynamic_cast<AudioTrack*>((*i).get())) {
2130 if (mute != currently_soloing) {
2132 currently_soloing = mute;
2135 if (!is_track && !mute) {
2137 /* nothing is soloed */
2139 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2140 (*i)->set_solo_mute (false);
2150 modify_solo_mute (is_track, mute);
2153 SoloActive (currently_soloing);
2158 Session::modify_solo_mute (bool is_track, bool mute)
2160 shared_ptr<RouteList> r = routes.reader ();
2162 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2166 /* only alter track solo mute */
2168 if (dynamic_cast<AudioTrack*>((*i).get())) {
2169 if ((*i)->soloed()) {
2170 (*i)->set_solo_mute (!mute);
2172 (*i)->set_solo_mute (mute);
2178 /* only alter bus solo mute */
2180 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2182 if ((*i)->soloed()) {
2184 (*i)->set_solo_mute (false);
2188 /* don't mute master or control outs
2189 in response to another bus solo
2192 if ((*i) != _master_out &&
2193 (*i) != _control_out) {
2194 (*i)->set_solo_mute (mute);
2205 Session::catch_up_on_solo ()
2207 /* this is called after set_state() to catch the full solo
2208 state, which can't be correctly determined on a per-route
2209 basis, but needs the global overview that only the session
2212 update_route_solo_state();
2216 Session::route_by_name (string name)
2218 shared_ptr<RouteList> r = routes.reader ();
2220 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2221 if ((*i)->name() == name) {
2226 return shared_ptr<Route> ((Route*) 0);
2230 Session::route_by_id (PBD::ID id)
2232 shared_ptr<RouteList> r = routes.reader ();
2234 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2235 if ((*i)->id() == id) {
2240 return shared_ptr<Route> ((Route*) 0);
2244 Session::route_by_remote_id (uint32_t id)
2246 shared_ptr<RouteList> r = routes.reader ();
2248 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2249 if ((*i)->remote_control_id() == id) {
2254 return shared_ptr<Route> ((Route*) 0);
2258 Session::find_current_end ()
2260 if (_state_of_the_state & Loading) {
2264 jack_nframes_t max = get_maximum_extent ();
2266 if (max > end_location->end()) {
2267 end_location->set_end (max);
2269 DurationChanged(); /* EMIT SIGNAL */
2274 Session::get_maximum_extent () const
2276 jack_nframes_t max = 0;
2279 /* Don't take the diskstream lock. Caller must have other ways to
2283 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2284 Playlist* pl = (*i)->playlist();
2285 if ((me = pl->get_maximum_extent()) > max) {
2294 Session::diskstream_by_name (string name)
2296 Glib::RWLock::ReaderLock lm (diskstream_lock);
2298 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2299 if ((*i)->name() == name) {
2308 Session::diskstream_by_id (const PBD::ID& id)
2310 Glib::RWLock::ReaderLock lm (diskstream_lock);
2312 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2313 if ((*i)->id() == id) {
2321 /* AudioRegion management */
2324 Session::new_region_name (string old)
2326 string::size_type last_period;
2328 string::size_type len = old.length() + 64;
2331 if ((last_period = old.find_last_of ('.')) == string::npos) {
2333 /* no period present - add one explicitly */
2336 last_period = old.length() - 1;
2341 number = atoi (old.substr (last_period+1).c_str());
2345 while (number < (UINT_MAX-1)) {
2347 AudioRegionList::const_iterator i;
2352 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2355 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2356 if (i->second->name() == sbuf) {
2361 if (i == audio_regions.end()) {
2366 if (number != (UINT_MAX-1)) {
2370 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2375 Session::region_name (string& result, string base, bool newlevel) const
2382 Glib::Mutex::Lock lm (region_lock);
2384 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2392 /* XXX this is going to be slow. optimize me later */
2397 string::size_type pos;
2399 pos = base.find_last_of ('.');
2401 /* pos may be npos, but then we just use entire base */
2403 subbase = base.substr (0, pos);
2407 bool name_taken = true;
2410 Glib::Mutex::Lock lm (region_lock);
2412 for (int n = 1; n < 5000; ++n) {
2415 snprintf (buf, sizeof (buf), ".%d", n);
2420 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2421 if (i->second->name() == result) {
2434 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2442 Session::add_region (Region* region)
2444 AudioRegion* ar = 0;
2445 AudioRegion* oar = 0;
2449 Glib::Mutex::Lock lm (region_lock);
2451 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2453 AudioRegionList::iterator x;
2455 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2457 oar = dynamic_cast<AudioRegion*> (x->second);
2459 if (ar->region_list_equivalent (*oar)) {
2464 if (x == audio_regions.end()) {
2466 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2468 entry.first = region->id();
2471 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2482 fatal << _("programming error: ")
2483 << X_("unknown region type passed to Session::add_region()")
2490 /* mark dirty because something has changed even if we didn't
2491 add the region to the region list.
2497 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2498 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2499 AudioRegionAdded (ar); /* EMIT SIGNAL */
2504 Session::region_changed (Change what_changed, Region* region)
2506 if (what_changed & Region::HiddenChanged) {
2507 /* relay hidden changes */
2508 RegionHiddenChange (region);
2513 Session::region_renamed (Region* region)
2515 add_region (region);
2519 Session::remove_region (Region* region)
2521 AudioRegionList::iterator i;
2522 AudioRegion* ar = 0;
2523 bool removed = false;
2526 Glib::Mutex::Lock lm (region_lock);
2528 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2529 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2530 audio_regions.erase (i);
2536 fatal << _("programming error: ")
2537 << X_("unknown region type passed to Session::remove_region()")
2543 /* mark dirty because something has changed even if we didn't
2544 remove the region from the region list.
2550 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2555 Session::find_whole_file_parent (AudioRegion& child)
2557 AudioRegionList::iterator i;
2558 AudioRegion* region;
2559 Glib::Mutex::Lock lm (region_lock);
2561 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2565 if (region->whole_file()) {
2567 if (child.source_equivalent (*region)) {
2577 Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
2579 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2580 (*i)->get_region_list_equivalent_regions (region, result);
2584 Session::destroy_region (Region* region)
2586 AudioRegion* aregion;
2588 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2592 if (aregion->playlist()) {
2593 aregion->playlist()->destroy_region (region);
2596 vector<Source*> srcs;
2598 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2599 srcs.push_back (&aregion->source (n));
2602 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2604 if ((*i)->use_cnt() == 0) {
2605 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2607 (afs)->mark_for_remove ();
2617 Session::destroy_regions (list<Region*> regions)
2619 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2620 destroy_region (*i);
2626 Session::remove_last_capture ()
2630 Glib::RWLock::ReaderLock lm (diskstream_lock);
2632 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2633 list<Region*>& l = (*i)->last_capture_regions();
2636 r.insert (r.end(), l.begin(), l.end());
2641 destroy_regions (r);
2646 Session::remove_region_from_region_list (Region& r)
2652 /* Source Management */
2655 Session::add_audio_source (AudioSource* source)
2657 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2660 Glib::Mutex::Lock lm (audio_source_lock);
2661 entry.first = source->id();
2662 entry.second = source;
2663 audio_sources.insert (entry);
2666 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2669 SourceAdded (source); /* EMIT SIGNAL */
2673 Session::remove_source (Source* source)
2675 AudioSourceList::iterator i;
2678 Glib::Mutex::Lock lm (audio_source_lock);
2680 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2681 audio_sources.erase (i);
2685 if (!_state_of_the_state & InCleanup) {
2687 /* save state so we don't end up with a session file
2688 referring to non-existent sources.
2691 save_state (_current_snapshot_name);
2692 save_history (_current_snapshot_name);
2695 SourceRemoved(source); /* EMIT SIGNAL */
2699 Session::source_by_id (const PBD::ID& id)
2701 Glib::Mutex::Lock lm (audio_source_lock);
2702 AudioSourceList::iterator i;
2705 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2709 /* XXX search MIDI or other searches here */
2715 Session::peak_path_from_audio_path (string audio_path)
2717 /* XXX hardly bombproof! fix me */
2721 res = Glib::path_get_dirname (audio_path);
2722 res = Glib::path_get_dirname (res);
2724 res += peak_dir_name;
2726 res += PBD::basename_nosuffix (audio_path);
2733 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2736 string old_basename = PBD::basename_nosuffix (oldname);
2737 string new_legalized = legalize_for_path (newname);
2739 /* note: we know (or assume) the old path is already valid */
2743 /* destructive file sources have a name of the form:
2745 /path/to/Tnnnn-NAME(%[LR])?.wav
2747 the task here is to replace NAME with the new name.
2750 /* find last slash */
2754 string::size_type slash;
2755 string::size_type dash;
2757 if ((slash = path.find_last_of ('/')) == string::npos) {
2761 dir = path.substr (0, slash+1);
2763 /* '-' is not a legal character for the NAME part of the path */
2765 if ((dash = path.find_last_of ('-')) == string::npos) {
2769 prefix = path.substr (slash+1, dash-(slash+1));
2774 path += new_legalized;
2775 path += ".wav"; /* XXX gag me with a spoon */
2779 /* non-destructive file sources have a name of the form:
2781 /path/to/NAME-nnnnn(%[LR])?.wav
2783 the task here is to replace NAME with the new name.
2788 string::size_type slash;
2789 string::size_type dash;
2790 string::size_type postfix;
2792 /* find last slash */
2794 if ((slash = path.find_last_of ('/')) == string::npos) {
2798 dir = path.substr (0, slash+1);
2800 /* '-' is not a legal character for the NAME part of the path */
2802 if ((dash = path.find_last_of ('-')) == string::npos) {
2806 suffix = path.substr (dash+1);
2808 // Suffix is now everything after the dash. Now we need to eliminate
2809 // the nnnnn part, which is done by either finding a '%' or a '.'
2811 postfix = suffix.find_last_of ("%");
2812 if (postfix == string::npos) {
2813 postfix = suffix.find_last_of ('.');
2816 if (postfix != string::npos) {
2817 suffix = suffix.substr (postfix);
2819 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2823 const uint32_t limit = 10000;
2824 char buf[PATH_MAX+1];
2826 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2828 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2830 if (access (buf, F_OK) != 0) {
2838 error << "FATAL ERROR! Could not find a " << endl;
2847 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2851 char buf[PATH_MAX+1];
2852 const uint32_t limit = 10000;
2856 legalized = legalize_for_path (name);
2858 /* find a "version" of the file name that doesn't exist in
2859 any of the possible directories.
2862 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2864 vector<space_and_path>::iterator i;
2865 uint32_t existing = 0;
2867 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2872 spath += tape_dir_name;
2874 spath += sound_dir_name;
2879 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2880 } else if (nchan == 2) {
2882 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2884 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2886 } else if (nchan < 26) {
2887 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2889 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2897 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2898 } else if (nchan == 2) {
2900 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2902 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2904 } else if (nchan < 26) {
2905 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2907 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2911 if (access (buf, F_OK) == 0) {
2916 if (existing == 0) {
2921 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2922 throw failed_constructor();
2926 /* we now have a unique name for the file, but figure out where to
2933 spath = tape_dir ();
2935 spath = discover_best_sound_dir ();
2938 string::size_type pos = foo.find_last_of ('/');
2940 if (pos == string::npos) {
2943 spath += foo.substr (pos + 1);
2950 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2952 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2954 /* this might throw failed_constructor(), which is OK */
2957 return new DestructiveFileSource (spath,
2958 Config->get_native_file_data_format(),
2959 Config->get_native_file_header_format(),
2962 return new SndFileSource (spath,
2963 Config->get_native_file_data_format(),
2964 Config->get_native_file_header_format(),
2969 /* Playlist management */
2972 Session::playlist_by_name (string name)
2974 Glib::Mutex::Lock lm (playlist_lock);
2975 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2976 if ((*i)->name() == name) {
2980 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2981 if ((*i)->name() == name) {
2989 Session::add_playlist (Playlist* playlist)
2991 if (playlist->hidden()) {
2996 Glib::Mutex::Lock lm (playlist_lock);
2997 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2998 playlists.insert (playlists.begin(), playlist);
3000 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3001 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
3007 PlaylistAdded (playlist); /* EMIT SIGNAL */
3011 Session::track_playlist (Playlist* pl, bool inuse)
3013 PlaylistList::iterator x;
3016 Glib::Mutex::Lock lm (playlist_lock);
3019 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3021 unused_playlists.insert (pl);
3023 if ((x = playlists.find (pl)) != playlists.end()) {
3024 playlists.erase (x);
3029 //cerr << "shifting playlist to used: " << pl->name() << endl;
3031 playlists.insert (pl);
3033 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3034 unused_playlists.erase (x);
3041 Session::remove_playlist (Playlist* playlist)
3043 if (_state_of_the_state & Deletion) {
3048 Glib::Mutex::Lock lm (playlist_lock);
3049 // cerr << "removing playlist: " << playlist->name() << endl;
3051 PlaylistList::iterator i;
3053 i = find (playlists.begin(), playlists.end(), playlist);
3055 if (i != playlists.end()) {
3056 playlists.erase (i);
3059 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3060 if (i != unused_playlists.end()) {
3061 unused_playlists.erase (i);
3068 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3072 Session::set_audition (AudioRegion* r)
3074 pending_audition_region = r;
3075 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3076 schedule_butler_transport_work ();
3080 Session::non_realtime_set_audition ()
3082 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3083 auditioner->audition_current_playlist ();
3084 } else if (pending_audition_region) {
3085 auditioner->audition_region (*pending_audition_region);
3087 pending_audition_region = 0;
3088 AuditionActive (true); /* EMIT SIGNAL */
3092 Session::audition_playlist ()
3094 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3095 ev->set_ptr ((void*) 0xfeedface);
3100 Session::audition_region (Region& r)
3102 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
3104 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3111 Session::cancel_audition ()
3113 if (auditioner->active()) {
3114 auditioner->cancel_audition ();
3115 AuditionActive (false); /* EMIT SIGNAL */
3120 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3122 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3126 Session::remove_empty_sounds ()
3129 PathScanner scanner;
3134 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3136 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3138 if (AudioFileSource::is_empty (*(*i))) {
3140 unlink ((*i)->c_str());
3142 string peak_path = peak_path_from_audio_path (**i);
3143 unlink (peak_path.c_str());
3149 delete possible_audiofiles;
3153 Session::is_auditioning () const
3155 /* can be called before we have an auditioner object */
3157 return auditioner->active();
3164 Session::set_all_solo (bool yn)
3166 shared_ptr<RouteList> r = routes.reader ();
3168 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3169 if (!(*i)->hidden()) {
3170 (*i)->set_solo (yn, this);
3178 Session::set_all_mute (bool yn)
3180 shared_ptr<RouteList> r = routes.reader ();
3182 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3183 if (!(*i)->hidden()) {
3184 (*i)->set_mute (yn, this);
3192 Session::n_diskstreams () const
3194 Glib::RWLock::ReaderLock lm (diskstream_lock);
3197 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3198 if (!(*i)->hidden()) {
3206 Session::graph_reordered ()
3208 /* don't do this stuff if we are setting up connections
3209 from a set_state() call.
3212 if (_state_of_the_state & InitialConnecting) {
3216 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3220 /* force all diskstreams to update their capture offset values to
3221 reflect any changes in latencies within the graph.
3224 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3225 (*i)->set_capture_offset ();
3230 Session::record_disenable_all ()
3232 record_enable_change_all (false);
3236 Session::record_enable_all ()
3238 record_enable_change_all (true);
3242 Session::record_enable_change_all (bool yn)
3244 shared_ptr<RouteList> r = routes.reader ();
3246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3249 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3250 at->set_record_enable (yn, this);
3254 /* since we don't keep rec-enable state, don't mark session dirty */
3258 Session::add_redirect (Redirect* redirect)
3262 PortInsert* port_insert;
3263 PluginInsert* plugin_insert;
3265 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3266 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3267 _port_inserts.insert (_port_inserts.begin(), port_insert);
3268 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3269 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3271 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3274 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3275 _sends.insert (_sends.begin(), send);
3277 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3281 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3287 Session::remove_redirect (Redirect* redirect)
3291 PortInsert* port_insert;
3292 PluginInsert* plugin_insert;
3294 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3295 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3296 _port_inserts.remove (port_insert);
3297 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3298 _plugin_inserts.remove (plugin_insert);
3300 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3303 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3304 _sends.remove (send);
3306 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3314 Session::available_capture_duration ()
3316 const double scale = 4096.0 / sizeof (Sample);
3318 if (_total_free_4k_blocks * scale > (double) max_frames) {
3322 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3326 Session::add_connection (ARDOUR::Connection* connection)
3329 Glib::Mutex::Lock guard (connection_lock);
3330 _connections.push_back (connection);
3333 ConnectionAdded (connection); /* EMIT SIGNAL */
3339 Session::remove_connection (ARDOUR::Connection* connection)
3341 bool removed = false;
3344 Glib::Mutex::Lock guard (connection_lock);
3345 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3347 if (i != _connections.end()) {
3348 _connections.erase (i);
3354 ConnectionRemoved (connection); /* EMIT SIGNAL */
3360 ARDOUR::Connection *
3361 Session::connection_by_name (string name) const
3363 Glib::Mutex::Lock lm (connection_lock);
3365 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3366 if ((*i)->name() == name) {
3375 Session::set_edit_mode (EditMode mode)
3380 Glib::Mutex::Lock lm (playlist_lock);
3382 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3383 (*i)->set_edit_mode (mode);
3388 ControlChanged (EditingMode); /* EMIT SIGNAL */
3392 Session::tempo_map_changed (Change ignored)
3399 Session::ensure_passthru_buffers (uint32_t howmany)
3401 while (howmany > _passthru_buffers.size()) {
3403 #ifdef NO_POSIX_MEMALIGN
3404 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3406 posix_memalign((void **)&p,16,current_block_size * 4);
3408 _passthru_buffers.push_back (p);
3412 #ifdef NO_POSIX_MEMALIGN
3413 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3415 posix_memalign((void **)&p,16,current_block_size * 4);
3417 memset (p, 0, sizeof (Sample) * current_block_size);
3418 _silent_buffers.push_back (p);
3422 #ifdef NO_POSIX_MEMALIGN
3423 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3425 posix_memalign((void **)&p,16,current_block_size * 4);
3427 memset (p, 0, sizeof (Sample) * current_block_size);
3428 _send_buffers.push_back (p);
3431 allocate_pan_automation_buffers (current_block_size, howmany, false);
3435 Session::next_send_name ()
3438 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3443 Session::next_insert_name ()
3446 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3450 /* Named Selection management */
3453 Session::named_selection_by_name (string name)
3455 Glib::Mutex::Lock lm (named_selection_lock);
3456 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3457 if ((*i)->name == name) {
3465 Session::add_named_selection (NamedSelection* named_selection)
3468 Glib::Mutex::Lock lm (named_selection_lock);
3469 named_selections.insert (named_selections.begin(), named_selection);
3474 NamedSelectionAdded (); /* EMIT SIGNAL */
3478 Session::remove_named_selection (NamedSelection* named_selection)
3480 bool removed = false;
3483 Glib::Mutex::Lock lm (named_selection_lock);
3485 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3487 if (i != named_selections.end()) {
3489 named_selections.erase (i);
3496 NamedSelectionRemoved (); /* EMIT SIGNAL */
3501 Session::reset_native_file_format ()
3503 // jlc - WHY take routelock?
3504 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3505 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3507 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3508 (*i)->reset_write_sources (false);
3513 Session::route_name_unique (string n) const
3515 shared_ptr<RouteList> r = routes.reader ();
3517 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3518 if ((*i)->name() == n) {
3527 Session::cleanup_audio_file_source (AudioFileSource& fs)
3529 return fs.move_to_trash (dead_sound_dir_name);
3533 Session::n_playlists () const
3535 Glib::Mutex::Lock lm (playlist_lock);
3536 return playlists.size();
3540 Session::set_solo_model (SoloModel sm)
3542 if (sm != _solo_model) {
3544 ControlChanged (SoloingModel);
3550 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3552 if (!force && howmany <= _npan_buffers) {
3556 if (_pan_automation_buffer) {
3558 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3559 delete [] _pan_automation_buffer[i];
3562 delete [] _pan_automation_buffer;
3565 _pan_automation_buffer = new pan_t*[howmany];
3567 for (uint32_t i = 0; i < howmany; ++i) {
3568 _pan_automation_buffer[i] = new pan_t[nframes];
3571 _npan_buffers = howmany;
3575 Session::freeze (InterThreadInfo& itt)
3577 shared_ptr<RouteList> r = routes.reader ();
3579 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3583 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3584 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3595 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3596 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3600 AudioFileSource* fsource;
3602 char buf[PATH_MAX+1];
3605 jack_nframes_t position;
3606 jack_nframes_t this_chunk;
3607 jack_nframes_t to_do;
3608 vector<Sample*> buffers;
3610 // any bigger than this seems to cause stack overflows in called functions
3611 const jack_nframes_t chunk_size = (128 * 1024)/4;
3613 g_atomic_int_set (&processing_prohibited, 1);
3615 /* call tree *MUST* hold route_lock */
3617 if ((playlist = track.diskstream().playlist()) == 0) {
3621 /* external redirects will be a problem */
3623 if (track.has_external_redirects()) {
3627 nchans = track.audio_diskstream().n_channels();
3629 dir = discover_best_sound_dir ();
3631 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3633 for (x = 0; x < 99999; ++x) {
3634 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3635 if (access (buf, F_OK) != 0) {
3641 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3646 fsource = new SndFileSource (buf,
3647 Config->get_native_file_data_format(),
3648 Config->get_native_file_header_format(),
3653 catch (failed_constructor& err) {
3654 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3658 srcs.push_back(fsource);
3661 /* XXX need to flush all redirects */
3666 /* create a set of reasonably-sized buffers */
3668 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3670 #ifdef NO_POSIX_MEMALIGN
3671 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3673 posix_memalign((void **)&b,16,chunk_size * 4);
3675 buffers.push_back (b);
3678 while (to_do && !itt.cancel) {
3680 this_chunk = min (to_do, chunk_size);
3682 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3687 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3688 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3691 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3697 start += this_chunk;
3698 to_do -= this_chunk;
3700 itt.progress = (float) (1.0 - ((double) to_do / len));
3709 xnow = localtime (&now);
3711 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3712 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3714 afs->update_header (position, *xnow, now);
3718 /* build peakfile for new source */
3720 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3721 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3723 afs->build_peaks ();
3732 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3733 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3735 afs->mark_for_remove ();
3741 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3745 g_atomic_int_set (&processing_prohibited, 0);
3753 Session::get_silent_buffers (uint32_t howmany)
3755 for (uint32_t i = 0; i < howmany; ++i) {
3756 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3758 return _silent_buffers;
3762 Session::ntracks () const
3765 shared_ptr<RouteList> r = routes.reader ();
3767 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3768 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3777 Session::nbusses () const
3780 shared_ptr<RouteList> r = routes.reader ();
3782 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3783 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3792 Session::set_layer_model (LayerModel lm)
3794 if (lm != layer_model) {
3797 ControlChanged (LayeringModel);
3802 Session::set_xfade_model (CrossfadeModel xm)
3804 if (xm != xfade_model) {
3807 ControlChanged (CrossfadingModel);
3812 Session::add_curve(Curve *curve)
3814 curves[curve->id()] = curve;
3818 Session::add_automation_list(AutomationList *al)
3820 automation_lists[al->id()] = al;