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 <pbd/error.h>
36 #include <pbd/lockmonitor.h>
37 #include <pbd/pathscanner.h>
38 #include <pbd/stl_delete.h>
39 #include <pbd/basename.h>
40 #include <pbd/dirname.h>
42 #include <ardour/audioengine.h>
43 #include <ardour/configuration.h>
44 #include <ardour/session.h>
45 #include <ardour/diskstream.h>
46 #include <ardour/utils.h>
47 #include <ardour/audioplaylist.h>
48 #include <ardour/audioregion.h>
49 #include <ardour/source.h>
50 #include <ardour/filesource.h>
51 #include <ardour/destructive_filesource.h>
52 #include <ardour/sndfilesource.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/timestamps.h>
72 using namespace ARDOUR;
73 //using namespace sigc;
75 const char* Session::_template_suffix = X_(".template");
76 const char* Session::_statefile_suffix = X_(".ardour");
77 const char* Session::_pending_suffix = X_(".pending");
78 const char* Session::sound_dir_name = X_("sounds");
79 const char* Session::tape_dir_name = X_("tapes");
80 const char* Session::peak_dir_name = X_("peaks");
81 const char* Session::dead_sound_dir_name = X_("dead_sounds");
83 Session::compute_peak_t Session::compute_peak = 0;
84 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
85 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
86 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
88 sigc::signal<int> Session::AskAboutPendingState;
91 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
98 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
99 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
105 /* check to see if it exists, and what it is */
107 if (stat (str.c_str(), &statbuf)) {
108 if (errno == ENOENT) {
111 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
119 /* it exists, so it must either be the name
120 of the directory, or the name of the statefile
124 if (S_ISDIR (statbuf.st_mode)) {
126 string::size_type slash = str.find_last_of ('/');
128 if (slash == string::npos) {
130 /* a subdirectory of cwd, so statefile should be ... */
136 tmp += _statefile_suffix;
140 if (stat (tmp.c_str(), &statbuf)) {
141 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
151 /* some directory someplace in the filesystem.
152 the snapshot name is the directory name
157 snapshot = str.substr (slash+1);
161 } else if (S_ISREG (statbuf.st_mode)) {
163 string::size_type slash = str.find_last_of ('/');
164 string::size_type suffix;
166 /* remove the suffix */
168 if (slash != string::npos) {
169 snapshot = str.substr (slash+1);
174 suffix = snapshot.find (_statefile_suffix);
176 if (suffix == string::npos) {
177 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
183 snapshot = snapshot.substr (0, suffix);
185 if (slash == string::npos) {
187 /* we must be in the directory where the
188 statefile lives. get it using cwd().
191 char cwd[PATH_MAX+1];
193 if (getcwd (cwd, sizeof (cwd)) == 0) {
194 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
203 /* full path to the statefile */
205 path = str.substr (0, slash);
210 /* what type of file is it? */
211 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
217 /* its the name of a new directory. get the name
221 string::size_type slash = str.find_last_of ('/');
223 if (slash == string::npos) {
225 /* no slash, just use the name, but clean it up */
227 path = legalize_for_path (str);
233 snapshot = str.substr (slash+1);
240 Session::Session (AudioEngine &eng,
242 string snapshot_name,
243 string* mix_template)
246 _mmc_port (default_mmc_port),
247 _mtc_port (default_mtc_port),
248 _midi_port (default_midi_port),
249 pending_events (2048),
250 midi_requests (128), // the size of this should match the midi request pool size
255 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
257 n_physical_outputs = _engine.n_physical_outputs();
258 n_physical_inputs = _engine.n_physical_inputs();
260 first_stage_init (fullpath, snapshot_name);
262 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
263 throw failed_constructor ();
266 if (second_stage_init (new_session)) {
267 throw failed_constructor ();
270 store_recent_sessions(_name, _path);
272 bool was_dirty = dirty();
274 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
277 DirtyChanged (); /* EMIT SIGNAL */
281 Session::Session (AudioEngine &eng,
283 string snapshot_name,
284 AutoConnectOption input_ac,
285 AutoConnectOption output_ac,
286 uint32_t control_out_channels,
287 uint32_t master_out_channels,
288 uint32_t requested_physical_in,
289 uint32_t requested_physical_out,
290 jack_nframes_t initial_length)
293 _mmc_port (default_mmc_port),
294 _mtc_port (default_mtc_port),
295 _midi_port (default_midi_port),
296 pending_events (2048),
303 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
305 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
306 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
308 first_stage_init (fullpath, snapshot_name);
310 if (create (new_session, 0, initial_length)) {
311 throw failed_constructor ();
314 if (control_out_channels) {
316 r = new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut);
321 if (master_out_channels) {
323 r = new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut);
327 /* prohibit auto-connect to master, because there isn't one */
328 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
331 input_auto_connect = input_ac;
332 output_auto_connect = output_ac;
334 if (second_stage_init (new_session)) {
335 throw failed_constructor ();
338 store_recent_sessions(_name, _path);
340 bool was_dirty = dirty ();
342 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
345 DirtyChanged (); /* EMIT SIGNAL */
351 /* if we got to here, leaving pending capture state around
355 remove_pending_capture_state ();
357 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
358 _engine.remove_session ();
360 going_away (); /* EMIT SIGNAL */
362 terminate_butler_thread ();
363 terminate_midi_thread ();
365 if (click_data && click_data != default_click) {
366 delete [] click_data;
369 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
370 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 routes\n";
444 #endif /* TRACK_DESTRUCTION */
445 for (RouteList::iterator i = routes.begin(); i != routes.end(); ) {
446 RouteList::iterator tmp;
453 #ifdef TRACK_DESTRUCTION
454 cerr << "delete diskstreams\n";
455 #endif /* TRACK_DESTRUCTION */
456 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
457 DiskStreamList::iterator tmp;
467 #ifdef TRACK_DESTRUCTION
468 cerr << "delete sources\n";
469 #endif /* TRACK_DESTRUCTION */
470 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
471 SourceList::iterator tmp;
481 #ifdef TRACK_DESTRUCTION
482 cerr << "delete mix groups\n";
483 #endif /* TRACK_DESTRUCTION */
484 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
485 list<RouteGroup*>::iterator tmp;
495 #ifdef TRACK_DESTRUCTION
496 cerr << "delete edit groups\n";
497 #endif /* TRACK_DESTRUCTION */
498 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
499 list<RouteGroup*>::iterator tmp;
509 #ifdef TRACK_DESTRUCTION
510 cerr << "delete connections\n";
511 #endif /* TRACK_DESTRUCTION */
512 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
513 ConnectionList::iterator tmp;
523 if (butler_mixdown_buffer) {
524 delete [] butler_mixdown_buffer;
527 if (butler_gain_buffer) {
528 delete [] butler_gain_buffer;
531 Crossfade::set_buffer_size (0);
543 Session::set_worst_io_latencies (bool take_lock)
545 _worst_output_latency = 0;
546 _worst_input_latency = 0;
548 if (!_engine.connected()) {
553 route_lock.read_lock ();
556 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
557 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
558 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
562 route_lock.unlock ();
567 Session::when_engine_running ()
569 string first_physical_output;
571 /* we don't want to run execute this again */
573 first_time_running.disconnect ();
575 set_block_size (_engine.frames_per_cycle());
576 set_frame_rate (_engine.frame_rate());
578 /* every time we reconnect, recompute worst case output latencies */
580 _engine.Running.connect (sigc::bind (mem_fun (*this, &Session::set_worst_io_latencies), true));
582 if (synced_to_jack()) {
583 _engine.transport_stop ();
586 if (Config->get_jack_time_master()) {
587 _engine.transport_locate (_transport_frame);
595 _click_io = new ClickIO (*this, "click", 0, 0, -1, -1);
597 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
599 /* existing state for Click */
601 if (_click_io->set_state (*child->children().front()) == 0) {
603 _clicking = click_requested;
607 error << _("could not setup Click I/O") << endmsg;
613 /* default state for Click */
615 first_physical_output = _engine.get_nth_physical_output (0);
617 if (first_physical_output.length()) {
618 if (_click_io->add_output_port (first_physical_output, this)) {
619 // relax, even though its an error
621 _clicking = click_requested;
627 catch (failed_constructor& err) {
628 error << _("cannot setup Click I/O") << endmsg;
631 set_worst_io_latencies (true);
634 ControlChanged (Clicking); /* EMIT SIGNAL */
637 if (auditioner == 0) {
639 /* we delay creating the auditioner till now because
640 it makes its own connections to ports named
641 in the ARDOUR_RC config file. the engine has
642 to be running for this to work.
646 auditioner = new Auditioner (*this);
649 catch (failed_constructor& err) {
650 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
654 /* Create a set of Connection objects that map
655 to the physical outputs currently available
660 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
662 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
664 Connection* c = new OutputConnection (buf, true);
667 c->add_connection (0, _engine.get_nth_physical_output (np));
672 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
674 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
676 Connection* c = new InputConnection (buf, true);
679 c->add_connection (0, _engine.get_nth_physical_input (np));
686 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
688 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
690 Connection* c = new OutputConnection (buf, true);
694 c->add_connection (0, _engine.get_nth_physical_output (np));
695 c->add_connection (1, _engine.get_nth_physical_output (np+1));
700 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
702 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
704 Connection* c = new InputConnection (buf, true);
708 c->add_connection (0, _engine.get_nth_physical_input (np));
709 c->add_connection (1, _engine.get_nth_physical_input (np+1));
718 /* create master/control ports */
723 /* force the master to ignore any later call to this */
725 if (_master_out->pending_state_node) {
726 _master_out->ports_became_legal();
729 /* no panner resets till we are through */
731 _master_out->defer_pan_reset ();
733 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
734 if (_master_out->add_input_port ("", this)) {
735 error << _("cannot setup master inputs")
741 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
742 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
743 error << _("cannot setup master outputs")
750 _master_out->allow_pan_reset ();
754 Connection* c = new OutputConnection (_("Master Out"), true);
756 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
758 c->add_connection ((int) n, _master_out->input(n)->name());
765 /* catch up on send+insert cnts */
769 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
772 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
773 if (id > insert_cnt) {
781 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
784 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
791 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
793 /* hook us up to the engine */
795 _engine.set_session (this);
797 _state_of_the_state = Clean;
799 DirtyChanged (); /* EMIT SIGNAL */
803 Session::hookup_io ()
805 /* stop graph reordering notifications from
806 causing resorts, etc.
809 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
811 /* Tell all IO objects to create their ports */
818 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
819 if (_control_out->add_input_port ("", this)) {
820 error << _("cannot setup control inputs")
826 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
827 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
828 error << _("cannot set up master outputs")
836 /* Tell all IO objects to connect themselves together */
838 IO::enable_connecting ();
840 /* Now reset all panners */
842 IO::reset_panners ();
844 /* Anyone who cares about input state, wake up and do something */
846 IOConnectionsComplete (); /* EMIT SIGNAL */
848 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
850 /* now handle the whole enchilada as if it was one
856 /* update mixer solo state */
862 Session::playlist_length_changed (Playlist* pl)
864 /* we can't just increase end_location->end() if pl->get_maximum_extent()
865 if larger. if the playlist used to be the longest playlist,
866 and its now shorter, we have to decrease end_location->end(). hence,
867 we have to iterate over all diskstreams and check the
868 playlists currently in use.
874 Session::diskstream_playlist_changed (DiskStream* dstream)
878 if ((playlist = dstream->playlist()) != 0) {
879 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
882 /* see comment in playlist_length_changed () */
887 Session::record_enabling_legal () const
889 /* this used to be in here, but survey says.... we don't need to restrict it */
890 // if (record_status() == Recording) {
901 Session::set_auto_play (bool yn)
903 if (auto_play != yn) {
906 ControlChanged (AutoPlay);
911 Session::set_auto_return (bool yn)
913 if (auto_return != yn) {
916 ControlChanged (AutoReturn);
921 Session::set_crossfades_active (bool yn)
923 if (crossfades_active != yn) {
924 crossfades_active = yn;
926 ControlChanged (CrossFadesActive);
931 Session::set_do_not_record_plugins (bool yn)
933 if (do_not_record_plugins != yn) {
934 do_not_record_plugins = yn;
936 ControlChanged (RecordingPlugins);
941 Session::set_auto_input (bool yn)
943 if (auto_input != yn) {
946 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
947 /* auto-input only makes a difference if we're rolling */
949 /* Even though this can called from RT context we are using
950 a non-tentative rwlock here, because the action must occur.
951 The rarity and short potential lock duration makes this "OK"
953 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
954 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
955 if ((*i)->record_enabled ()) {
956 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
957 (*i)->monitor_input (!auto_input);
963 ControlChanged (AutoInput);
968 Session::reset_input_monitor_state ()
970 if (transport_rolling()) {
971 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
972 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
973 if ((*i)->record_enabled ()) {
974 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
975 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
979 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
980 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
981 if ((*i)->record_enabled ()) {
982 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
983 (*i)->monitor_input (Config->get_use_hardware_monitoring());
991 Session::set_input_auto_connect (bool yn)
994 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
996 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1002 Session::get_input_auto_connect () const
1004 return (input_auto_connect & AutoConnectPhysical);
1008 Session::set_output_auto_connect (AutoConnectOption aco)
1010 output_auto_connect = aco;
1015 Session::auto_punch_start_changed (Location* location)
1017 replace_event (Event::PunchIn, location->start());
1019 if (get_record_enabled() && get_punch_in()) {
1020 /* capture start has been changed, so save new pending state */
1021 save_state ("", true);
1026 Session::auto_punch_end_changed (Location* location)
1028 jack_nframes_t when_to_stop = location->end();
1029 // when_to_stop += _worst_output_latency + _worst_input_latency;
1030 replace_event (Event::PunchOut, when_to_stop);
1034 Session::auto_punch_changed (Location* location)
1036 jack_nframes_t when_to_stop = location->end();
1038 replace_event (Event::PunchIn, location->start());
1039 //when_to_stop += _worst_output_latency + _worst_input_latency;
1040 replace_event (Event::PunchOut, when_to_stop);
1044 Session::auto_loop_changed (Location* location)
1046 replace_event (Event::AutoLoop, location->end(), location->start());
1048 if (transport_rolling() && get_auto_loop()) {
1050 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1052 if (_transport_frame > location->end()) {
1053 // relocate to beginning of loop
1054 clear_events (Event::LocateRoll);
1056 request_locate (location->start(), true);
1059 else if (seamless_loop && !loop_changing) {
1061 // schedule a locate-roll to refill the diskstreams at the
1062 // previous loop end
1063 loop_changing = true;
1065 if (location->end() > last_loopend) {
1066 clear_events (Event::LocateRoll);
1067 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1074 last_loopend = location->end();
1079 Session::set_auto_punch_location (Location* location)
1083 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1084 auto_punch_start_changed_connection.disconnect();
1085 auto_punch_end_changed_connection.disconnect();
1086 auto_punch_changed_connection.disconnect();
1087 existing->set_auto_punch (false, this);
1088 remove_event (existing->start(), Event::PunchIn);
1089 clear_events (Event::PunchOut);
1090 auto_punch_location_changed (0);
1095 if (location == 0) {
1099 if (location->end() <= location->start()) {
1100 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1104 auto_punch_start_changed_connection.disconnect();
1105 auto_punch_end_changed_connection.disconnect();
1106 auto_punch_changed_connection.disconnect();
1108 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1109 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1110 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1112 location->set_auto_punch (true, this);
1113 auto_punch_location_changed (location);
1117 Session::set_punch_in (bool yn)
1119 if (punch_in == yn) {
1125 if ((location = _locations.auto_punch_location()) != 0) {
1126 if ((punch_in = yn) == true) {
1127 replace_event (Event::PunchIn, location->start());
1129 remove_event (location->start(), Event::PunchIn);
1134 ControlChanged (PunchIn); /* EMIT SIGNAL */
1138 Session::set_punch_out (bool yn)
1140 if (punch_out == yn) {
1146 if ((location = _locations.auto_punch_location()) != 0) {
1147 if ((punch_out = yn) == true) {
1148 replace_event (Event::PunchOut, location->end());
1150 clear_events (Event::PunchOut);
1155 ControlChanged (PunchOut); /* EMIT SIGNAL */
1159 Session::set_auto_loop_location (Location* location)
1163 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1164 auto_loop_start_changed_connection.disconnect();
1165 auto_loop_end_changed_connection.disconnect();
1166 auto_loop_changed_connection.disconnect();
1167 existing->set_auto_loop (false, this);
1168 remove_event (existing->end(), Event::AutoLoop);
1169 auto_loop_location_changed (0);
1174 if (location == 0) {
1178 if (location->end() <= location->start()) {
1179 error << _("Session: you can't use a mark for auto loop") << endmsg;
1183 last_loopend = location->end();
1185 auto_loop_start_changed_connection.disconnect();
1186 auto_loop_end_changed_connection.disconnect();
1187 auto_loop_changed_connection.disconnect();
1189 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1190 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1191 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1193 location->set_auto_loop (true, this);
1194 auto_loop_location_changed (location);
1198 Session::locations_added (Location* ignored)
1204 Session::locations_changed ()
1206 _locations.apply (*this, &Session::handle_locations_changed);
1210 Session::handle_locations_changed (Locations::LocationList& locations)
1212 Locations::LocationList::iterator i;
1214 bool set_loop = false;
1215 bool set_punch = false;
1217 for (i = locations.begin(); i != locations.end(); ++i) {
1221 if (location->is_auto_punch()) {
1222 set_auto_punch_location (location);
1225 if (location->is_auto_loop()) {
1226 set_auto_loop_location (location);
1233 set_auto_loop_location (0);
1236 set_auto_punch_location (0);
1243 Session::enable_record ()
1245 /* XXX really atomic compare+swap here */
1246 if (atomic_read (&_record_status) != Recording) {
1247 atomic_set (&_record_status, Recording);
1248 _last_record_location = _transport_frame;
1249 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1251 if (Config->get_use_hardware_monitoring() && auto_input) {
1252 /* Even though this can be called from RT context we are using
1253 a non-tentative rwlock here, because the action must occur.
1254 The rarity and short potential lock duration makes this "OK"
1256 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1258 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1259 if ((*i)->record_enabled ()) {
1260 (*i)->monitor_input (true);
1265 RecordStateChanged ();
1270 Session::disable_record (bool rt_context, bool force)
1274 if ((rs = (RecordState) atomic_read (&_record_status)) != Disabled) {
1276 if (!Config->get_latched_record_enable () || force) {
1277 atomic_set (&_record_status, Disabled);
1279 if (rs == Recording) {
1280 atomic_set (&_record_status, Enabled);
1284 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1286 if (Config->get_use_hardware_monitoring() && auto_input) {
1287 /* Even though this can be called from RT context we are using
1288 a non-tentative rwlock here, because the action must occur.
1289 The rarity and short potential lock duration makes this "OK"
1291 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1293 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1294 if ((*i)->record_enabled ()) {
1295 (*i)->monitor_input (false);
1300 RecordStateChanged (); /* emit signal */
1303 remove_pending_capture_state ();
1309 Session::step_back_from_record ()
1311 atomic_set (&_record_status, Enabled);
1313 if (Config->get_use_hardware_monitoring()) {
1314 /* Even though this can be called from RT context we are using
1315 a non-tentative rwlock here, because the action must occur.
1316 The rarity and short potential lock duration makes this "OK"
1318 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1320 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1321 if (auto_input && (*i)->record_enabled ()) {
1322 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1323 (*i)->monitor_input (false);
1330 Session::maybe_enable_record ()
1332 atomic_set (&_record_status, Enabled);
1334 /* XXX this save should really happen in another thread. its needed so that
1335 pending capture state can be recovered if we crash.
1338 save_state ("", true);
1340 if (_transport_speed) {
1345 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1346 RecordStateChanged (); /* EMIT SIGNAL */
1353 Session::audible_frame () const
1356 jack_nframes_t offset;
1359 /* the first of these two possible settings for "offset"
1360 mean that the audible frame is stationary until
1361 audio emerges from the latency compensation
1364 the second means that the audible frame is stationary
1365 until audio would emerge from a physical port
1366 in the absence of any plugin latency compensation
1369 offset = _worst_output_latency;
1371 if (offset > current_block_size) {
1372 offset -= current_block_size;
1374 /* XXX is this correct? if we have no external
1375 physical connections and everything is internal
1376 then surely this is zero? still, how
1377 likely is that anyway?
1379 offset = current_block_size;
1382 if (synced_to_jack()) {
1383 tf = _engine.transport_frame();
1385 tf = _transport_frame;
1388 if (_transport_speed == 0) {
1398 if (!non_realtime_work_pending()) {
1402 /* take latency into account */
1411 Session::set_frame_rate (jack_nframes_t frames_per_second)
1413 /** \fn void Session::set_frame_size(jack_nframes_t)
1414 the AudioEngine object that calls this guarantees
1415 that it will not be called while we are also in
1416 ::process(). Its fine to do things that block
1420 _current_frame_rate = frames_per_second;
1421 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1423 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1427 /* XXX need to reset/reinstantiate all LADSPA plugins */
1431 Session::set_block_size (jack_nframes_t nframes)
1433 /* the AudioEngine guarantees
1434 that it will not be called while we are also in
1435 ::process(). It is therefore fine to do things that block
1440 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1441 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1442 vector<Sample*>::iterator i;
1445 current_block_size = nframes;
1447 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1451 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1455 _passthru_buffers.clear ();
1456 _silent_buffers.clear ();
1458 ensure_passthru_buffers (np);
1460 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1464 #ifdef NO_POSIX_MEMALIGN
1465 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1467 posix_memalign((void **)&buf,16,current_block_size * 4);
1471 memset (*i, 0, sizeof (Sample) * current_block_size);
1475 if (_gain_automation_buffer) {
1476 delete [] _gain_automation_buffer;
1478 _gain_automation_buffer = new gain_t[nframes];
1480 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1482 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1483 (*i)->set_block_size (nframes);
1486 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1487 (*i)->set_block_size (nframes);
1490 set_worst_io_latencies (false);
1495 Session::set_default_fade (float steepness, float fade_msecs)
1498 jack_nframes_t fade_frames;
1500 /* Don't allow fade of less 1 frame */
1502 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1509 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1513 default_fade_msecs = fade_msecs;
1514 default_fade_steepness = steepness;
1517 // jlc, WTF is this!
1518 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1519 AudioRegion::set_default_fade (steepness, fade_frames);
1524 /* XXX have to do this at some point */
1525 /* foreach region using default fade, reset, then
1526 refill_all_diskstream_buffers ();
1531 struct RouteSorter {
1532 bool operator() (Route* r1, Route* r2) {
1533 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1535 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1538 if (r1->fed_by.empty()) {
1539 if (r2->fed_by.empty()) {
1540 /* no ardour-based connections inbound to either route. just use signal order */
1541 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1543 /* r2 has connections, r1 does not; run r1 early */
1547 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1554 trace_terminal (Route* r1, Route* rbase)
1558 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1559 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1563 /* make a copy of the existing list of routes that feed r1 */
1565 set<Route *> existing = r1->fed_by;
1567 /* for each route that feeds r1, recurse, marking it as feeding
1571 for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
1574 /* r2 is a route that feeds r1 which somehow feeds base. mark
1575 base as being fed by r2
1578 rbase->fed_by.insert (r2);
1582 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1586 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1590 /* now recurse, so that we can mark base as being fed by
1591 all routes that feed r2
1594 trace_terminal (r2, rbase);
1601 Session::resort_routes (void* src)
1603 /* don't do anything here with signals emitted
1604 by Routes while we are being destroyed.
1607 if (_state_of_the_state & Deletion) {
1611 /* Caller MUST hold the route_lock */
1613 RouteList::iterator i, j;
1615 for (i = routes.begin(); i != routes.end(); ++i) {
1617 (*i)->fed_by.clear ();
1619 for (j = routes.begin(); j != routes.end(); ++j) {
1621 /* although routes can feed themselves, it will
1622 cause an endless recursive descent if we
1623 detect it. so don't bother checking for
1631 if ((*j)->feeds (*i)) {
1632 (*i)->fed_by.insert (*j);
1637 for (i = routes.begin(); i != routes.end(); ++i) {
1638 trace_terminal (*i, *i);
1645 cerr << "finished route resort\n";
1647 for (i = routes.begin(); i != routes.end(); ++i) {
1648 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1656 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1659 char track_name[32];
1661 uint32_t channels_used = 0;
1663 uint32_t nphysical_in;
1664 uint32_t nphysical_out;
1666 /* count existing audio tracks */
1669 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1670 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1671 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1672 if (!(*i)->hidden()) {
1674 channels_used += (*i)->n_inputs();
1680 /* check for duplicate route names, since we might have pre-existing
1681 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1682 save, close,restart,add new route - first named route is now
1687 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1688 if (route_by_name (track_name) == 0) {
1693 } while (n < (UINT_MAX-1));
1695 if (input_auto_connect & AutoConnectPhysical) {
1696 nphysical_in = n_physical_inputs;
1701 if (output_auto_connect & AutoConnectPhysical) {
1702 nphysical_out = n_physical_outputs;
1708 track = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1710 if (track->ensure_io (input_channels, output_channels, false, this)) {
1711 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1712 input_channels, output_channels)
1717 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1721 if (input_auto_connect & AutoConnectPhysical) {
1722 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1725 if (port.length() && track->connect_input (track->input (x), port, this)) {
1731 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1735 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1736 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1737 } else if (output_auto_connect & AutoConnectMaster) {
1739 port = _master_out->input (x%_master_out->n_inputs())->name();
1743 if (port.length() && track->connect_output (track->output (x), port, this)) {
1749 vector<string> cports;
1750 uint32_t ni = _control_out->n_inputs();
1752 for (n = 0; n < ni; ++n) {
1753 cports.push_back (_control_out->input(n)->name());
1756 track->set_control_outs (cports);
1759 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1763 track->set_remote_control_id (ntracks());
1766 catch (failed_constructor &err) {
1767 error << _("Session: could not create new audio track.") << endmsg;
1775 Session::new_audio_route (int input_channels, int output_channels)
1782 /* count existing audio busses */
1785 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1786 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1787 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1788 if (!(*i)->hidden()) {
1796 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1797 if (route_by_name (bus_name) == 0) {
1802 } while (n < (UINT_MAX-1));
1805 bus = new Route (*this, bus_name, -1, -1, -1, -1);
1807 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1808 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1809 input_channels, output_channels)
1813 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1817 if (input_auto_connect & AutoConnectPhysical) {
1818 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1821 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1826 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1830 if (output_auto_connect & AutoConnectPhysical) {
1831 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1832 } else if (output_auto_connect & AutoConnectMaster) {
1834 port = _master_out->input (x%_master_out->n_inputs())->name();
1838 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1844 vector<string> cports;
1845 uint32_t ni = _control_out->n_inputs();
1847 for (uint32_t n = 0; n < ni; ++n) {
1848 cports.push_back (_control_out->input(n)->name());
1850 bus->set_control_outs (cports);
1856 catch (failed_constructor &err) {
1857 error << _("Session: could not create new route.") << endmsg;
1865 Session::add_route (Route* route)
1868 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1869 routes.push_front (route);
1873 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1874 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1875 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1876 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1878 if (route->master()) {
1879 _master_out = route;
1882 if (route->control()) {
1883 _control_out = route;
1886 AudioTrack* at = dynamic_cast<AudioTrack*>(route);
1887 if (at && at->mode() == Destructive) {
1888 destructive_index++;
1892 save_state (_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(0, 0, 0);
1904 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
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);
1925 DiskStreamAdded (dstream); /* EMIT SIGNAL */
1929 Session::remove_route (Route& route)
1932 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1933 routes.remove (&route);
1935 /* deleting the master out seems like a dumb
1936 idea, but its more of a UI policy issue
1940 if (&route == _master_out) {
1944 if (&route == _control_out) {
1947 /* cancel control outs for all routes */
1949 vector<string> empty;
1951 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
1952 (*r)->set_control_outs (empty);
1956 update_route_solo_state ();
1960 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1964 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
1965 diskstreams.remove (&at->disk_stream());
1966 at->disk_stream().unref ();
1969 find_current_end ();
1972 update_latency_compensation (false, false);
1975 /* XXX should we disconnect from the Route's signals ? */
1977 save_state (_current_snapshot_name);
1983 Session::route_mute_changed (void* src)
1989 Session::route_solo_changed (void* src, Route* route)
1991 if (solo_update_disabled) {
1996 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1999 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
2001 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2003 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2007 /* don't mess with busses */
2009 if (dynamic_cast<AudioTrack*>(*i) == 0) {
2015 /* don't mess with tracks */
2017 if (dynamic_cast<AudioTrack*>(*i) != 0) {
2022 if ((*i) != route &&
2023 ((*i)->mix_group () == 0 ||
2024 (*i)->mix_group () != route->mix_group () ||
2025 !route->mix_group ()->is_active())) {
2027 if ((*i)->soloed()) {
2029 /* if its already soloed, and solo latching is enabled,
2030 then leave it as it is.
2033 if (_solo_latched) {
2040 solo_update_disabled = true;
2041 (*i)->set_solo (false, src);
2042 solo_update_disabled = false;
2046 bool something_soloed = false;
2047 bool same_thing_soloed = false;
2048 bool signal = false;
2050 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2051 if ((*i)->soloed()) {
2052 something_soloed = true;
2053 if (dynamic_cast<AudioTrack*>(*i)) {
2055 same_thing_soloed = true;
2060 same_thing_soloed = true;
2068 if (something_soloed != currently_soloing) {
2070 currently_soloing = something_soloed;
2073 modify_solo_mute (is_track, same_thing_soloed);
2076 SoloActive (currently_soloing);
2083 Session::set_solo_latched (bool yn)
2085 if (yn != _solo_latched) {
2088 ControlChanged (SoloLatch);
2093 Session::update_route_solo_state ()
2096 bool is_track = false;
2097 bool signal = false;
2099 /* caller must hold RouteLock */
2101 /* this is where we actually implement solo by changing
2102 the solo mute setting of each track.
2105 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2106 if ((*i)->soloed()) {
2108 if (dynamic_cast<AudioTrack*>(*i)) {
2115 if (mute != currently_soloing) {
2117 currently_soloing = mute;
2120 if (!is_track && !mute) {
2122 /* nothing is soloed */
2124 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2125 (*i)->set_solo_mute (false);
2135 modify_solo_mute (is_track, mute);
2138 SoloActive (currently_soloing);
2143 Session::modify_solo_mute (bool is_track, bool mute)
2145 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2149 /* only alter track solo mute */
2151 if (dynamic_cast<AudioTrack*>(*i)) {
2152 if ((*i)->soloed()) {
2153 (*i)->set_solo_mute (!mute);
2155 (*i)->set_solo_mute (mute);
2161 /* only alter bus solo mute */
2163 if (!dynamic_cast<AudioTrack*>(*i)) {
2165 if ((*i)->soloed()) {
2167 (*i)->set_solo_mute (false);
2171 /* don't mute master or control outs
2172 in response to another bus solo
2175 if ((*i) != _master_out &&
2176 (*i) != _control_out) {
2177 (*i)->set_solo_mute (mute);
2188 Session::catch_up_on_solo ()
2190 /* this is called after set_state() to catch the full solo
2191 state, which can't be correctly determined on a per-route
2192 basis, but needs the global overview that only the session
2195 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2196 update_route_solo_state();
2200 Session::route_by_name (string name)
2202 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2204 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2205 if ((*i)->name() == name) {
2214 Session::route_by_remote_id (uint32_t id)
2216 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2218 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2219 if ((*i)->remote_control_id() == id) {
2228 Session::find_current_end ()
2230 jack_nframes_t max = 0;
2233 if (_state_of_the_state & Loading) {
2237 /* Don't take the diskstream lock. Caller must have other ways to
2241 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2242 Playlist* pl = (*i)->playlist();
2243 if ((me = pl->get_maximum_extent()) > max) {
2248 if (max > end_location->end()) {
2249 end_location->set_end (max);
2251 DurationChanged(); /* EMIT SIGNAL */
2256 Session::diskstream_by_name (string name)
2258 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2260 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2261 if ((*i)->name() == name) {
2270 Session::diskstream_by_id (id_t id)
2272 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2274 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2275 if ((*i)->id() == id) {
2283 /* AudioRegion management */
2286 Session::new_region_name (string old)
2288 string::size_type last_period;
2290 string::size_type len = old.length() + 64;
2293 if ((last_period = old.find_last_of ('.')) == string::npos) {
2295 /* no period present - add one explicitly */
2298 last_period = old.length() - 1;
2303 number = atoi (old.substr (last_period+1).c_str());
2307 while (number < (UINT_MAX-1)) {
2309 AudioRegionList::const_iterator i;
2314 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2317 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2318 if ((*i).second->name() == sbuf) {
2323 if (i == audio_regions.end()) {
2328 if (number != (UINT_MAX-1)) {
2332 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2337 Session::region_name (string& result, string base, bool newlevel) const
2344 LockMonitor lm (region_lock, __LINE__, __FILE__);
2346 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2354 /* XXX this is going to be slow. optimize me later */
2359 string::size_type pos;
2361 pos = base.find_last_of ('.');
2363 /* pos may be npos, but then we just use entire base */
2365 subbase = base.substr (0, pos);
2369 bool name_taken = true;
2372 LockMonitor lm (region_lock, __LINE__, __FILE__);
2374 for (int n = 1; n < 5000; ++n) {
2377 snprintf (buf, sizeof (buf), ".%d", n);
2382 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2383 if ((*i).second->name() == result) {
2396 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2404 Session::add_region (Region* region)
2406 AudioRegion* ar = 0;
2407 AudioRegion* oar = 0;
2411 LockMonitor lm (region_lock, __LINE__, __FILE__);
2413 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2415 AudioRegionList::iterator x;
2417 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2419 oar = dynamic_cast<AudioRegion*> (x->second);
2421 if (ar->region_list_equivalent (*oar)) {
2426 if (x == audio_regions.end()) {
2428 pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry;
2430 entry.first = region->id();
2433 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2444 fatal << _("programming error: ")
2445 << X_("unknown region type passed to Session::add_region()")
2452 /* mark dirty because something has changed even if we didn't
2453 add the region to the region list.
2459 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2460 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2461 AudioRegionAdded (ar); /* EMIT SIGNAL */
2466 Session::region_changed (Change what_changed, Region* region)
2468 if (what_changed & Region::HiddenChanged) {
2469 /* relay hidden changes */
2470 RegionHiddenChange (region);
2475 Session::region_renamed (Region* region)
2477 add_region (region);
2481 Session::remove_region (Region* region)
2483 AudioRegionList::iterator i;
2484 AudioRegion* ar = 0;
2485 bool removed = false;
2488 LockMonitor lm (region_lock, __LINE__, __FILE__);
2490 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2491 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2492 audio_regions.erase (i);
2496 fatal << _("programming error: ")
2497 << X_("unknown region type passed to Session::remove_region()")
2503 /* mark dirty because something has changed even if we didn't
2504 remove the region from the region list.
2510 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2515 Session::find_whole_file_parent (AudioRegion& child)
2517 AudioRegionList::iterator i;
2518 AudioRegion* region;
2519 LockMonitor lm (region_lock, __LINE__, __FILE__);
2521 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2523 region = (*i).second;
2525 if (region->whole_file()) {
2527 if (child.source_equivalent (*region)) {
2537 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2539 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2543 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2547 pl->get_region_list_equivalent_regions (region, result);
2552 Session::destroy_region (Region* region)
2554 AudioRegion* aregion;
2556 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2560 if (aregion->playlist()) {
2561 aregion->playlist()->destroy_region (region);
2564 vector<Source*> srcs;
2566 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2567 srcs.push_back (&aregion->source (n));
2570 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2572 if ((*i)->use_cnt() == 0) {
2573 (*i)->mark_for_remove ();
2582 Session::destroy_regions (list<Region*> regions)
2584 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2585 destroy_region (*i);
2591 Session::remove_last_capture ()
2595 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2597 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2598 list<Region*>& l = (*i)->last_capture_regions();
2601 r.insert (r.end(), l.begin(), l.end());
2606 destroy_regions (r);
2611 Session::remove_region_from_region_list (Region& r)
2617 /* Source Management */
2620 Session::add_source (Source* source)
2622 pair<SourceList::key_type, SourceList::mapped_type> entry;
2625 LockMonitor lm (source_lock, __LINE__, __FILE__);
2626 entry.first = source->id();
2627 entry.second = source;
2628 sources.insert (entry);
2631 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2634 SourceAdded (source); /* EMIT SIGNAL */
2638 Session::remove_source (Source* source)
2640 SourceList::iterator i;
2643 LockMonitor lm (source_lock, __LINE__, __FILE__);
2645 if ((i = sources.find (source->id())) != sources.end()) {
2650 if (!_state_of_the_state & InCleanup) {
2652 /* save state so we don't end up with a session file
2653 referring to non-existent sources.
2656 save_state (_current_snapshot_name);
2659 SourceRemoved(source); /* EMIT SIGNAL */
2663 Session::get_source (ARDOUR::id_t id)
2665 LockMonitor lm (source_lock, __LINE__, __FILE__);
2666 SourceList::iterator i;
2669 if ((i = sources.find (id)) != sources.end()) {
2670 source = (*i).second;
2677 Session::peak_path_from_audio_path (string audio_path)
2679 /* XXX hardly bombproof! fix me */
2683 res = PBD::dirname (audio_path);
2684 res = PBD::dirname (res);
2686 res += peak_dir_name;
2688 res += PBD::basename_nosuffix (audio_path);
2695 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2698 string old_basename = basename_nosuffix (oldname);
2699 string new_legalized = legalize_for_path (newname);
2701 /* note: we know (or assume) the old path is already valid */
2705 /* destructive file sources have a name of the form:
2707 /path/to/Tnnnn-NAME(%[LR])?.wav
2709 the task here is to replace NAME with the new name.
2712 /* find last slash */
2716 string::size_type slash;
2717 string::size_type dash;
2719 if ((slash = path.find_last_of ('/')) == string::npos) {
2723 dir = path.substr (0, slash+1);
2725 /* '-' is not a legal character for the NAME part of the path */
2727 if ((dash = path.find_last_of ('-')) == string::npos) {
2731 prefix = path.substr (slash+1, dash-(slash+1));
2736 path += new_legalized;
2737 path += ".wav"; /* XXX gag me with a spoon */
2741 /* non-destructive file sources have a name of the form:
2743 /path/to/NAME-nnnnn(%[LR])?.wav
2745 the task here is to replace NAME with the new name.
2748 /* find last slash */
2752 string::size_type slash;
2753 string::size_type dash;
2755 if ((slash = path.find_last_of ('/')) == string::npos) {
2759 dir = path.substr (0, slash+1);
2761 /* '-' is not a legal character for the NAME part of the path */
2763 if ((dash = path.find_last_of ('-')) == string::npos) {
2767 suffix = path.substr (dash);
2770 path += new_legalized;
2778 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2782 char buf[PATH_MAX+1];
2783 const uint32_t limit = 10000;
2787 legalized = legalize_for_path (name);
2789 /* find a "version" of the file name that doesn't exist in
2790 any of the possible directories.
2793 for (cnt = (destructive ? destructive_index + 1 : 1); cnt <= limit; ++cnt) {
2795 vector<space_and_path>::iterator i;
2796 uint32_t existing = 0;
2798 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2803 spath += tape_dir_name;
2805 spath += sound_dir_name;
2810 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2811 } else if (nchan == 2) {
2813 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2815 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2817 } else if (nchan < 26) {
2818 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2820 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2828 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2829 } else if (nchan == 2) {
2831 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2833 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2835 } else if (nchan < 26) {
2836 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2838 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2842 if (access (buf, F_OK) == 0) {
2847 if (existing == 0) {
2852 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2853 throw failed_constructor();
2857 /* we now have a unique name for the file, but figure out where to
2864 spath = tape_dir ();
2866 spath = discover_best_sound_dir ();
2869 string::size_type pos = foo.find_last_of ('/');
2871 if (pos == string::npos) {
2874 spath += foo.substr (pos + 1);
2881 Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
2883 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2885 /* this might throw failed_constructor(), which is OK */
2888 return new DestructiveFileSource (spath, frame_rate(), false, Config->get_native_file_data_format());
2890 return new FileSource (spath, frame_rate(), false, Config->get_native_file_data_format());
2894 /* Playlist management */
2897 Session::get_playlist (string name)
2901 if ((ret = playlist_by_name (name)) == 0) {
2902 ret = new AudioPlaylist (*this, name);
2909 Session::playlist_by_name (string name)
2911 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2912 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2913 if ((*i)->name() == name) {
2917 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2918 if ((*i)->name() == name) {
2926 Session::add_playlist (Playlist* playlist)
2928 if (playlist->hidden()) {
2933 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2934 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2935 playlists.insert (playlists.begin(), playlist);
2937 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2938 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2944 PlaylistAdded (playlist); /* EMIT SIGNAL */
2948 Session::track_playlist (Playlist* pl, bool inuse)
2950 PlaylistList::iterator x;
2953 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2956 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2958 unused_playlists.insert (pl);
2960 if ((x = playlists.find (pl)) != playlists.end()) {
2961 playlists.erase (x);
2966 //cerr << "shifting playlist to used: " << pl->name() << endl;
2968 playlists.insert (pl);
2970 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2971 unused_playlists.erase (x);
2978 Session::remove_playlist (Playlist* playlist)
2980 if (_state_of_the_state & Deletion) {
2985 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2986 // cerr << "removing playlist: " << playlist->name() << endl;
2988 PlaylistList::iterator i;
2990 i = find (playlists.begin(), playlists.end(), playlist);
2992 if (i != playlists.end()) {
2993 playlists.erase (i);
2996 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
2997 if (i != unused_playlists.end()) {
2998 unused_playlists.erase (i);
3005 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3009 Session::set_audition (AudioRegion* r)
3011 pending_audition_region = r;
3012 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3013 schedule_butler_transport_work ();
3017 Session::non_realtime_set_audition ()
3019 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3020 auditioner->audition_current_playlist ();
3021 } else if (pending_audition_region) {
3022 auditioner->audition_region (*pending_audition_region);
3024 pending_audition_region = 0;
3025 AuditionActive (true); /* EMIT SIGNAL */
3029 Session::audition_playlist ()
3031 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3032 ev->set_ptr ((void*) 0xfeedface);
3037 Session::audition_region (AudioRegion& r)
3039 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3045 Session::cancel_audition ()
3047 if (auditioner->active()) {
3048 auditioner->cancel_audition ();
3049 AuditionActive (false); /* EMIT SIGNAL */
3054 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
3056 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3060 Session::remove_empty_sounds ()
3063 PathScanner scanner;
3068 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3070 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3072 if (FileSource::is_empty (*(*i))) {
3074 unlink ((*i)->c_str());
3076 string peak_path = peak_path_from_audio_path (**i);
3077 unlink (peak_path.c_str());
3083 delete possible_audiofiles;
3087 Session::is_auditioning () const
3089 /* can be called before we have an auditioner object */
3091 return auditioner->active();
3098 Session::set_all_solo (bool yn)
3101 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3103 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3104 if (!(*i)->hidden()) {
3105 (*i)->set_solo (yn, this);
3114 Session::set_all_mute (bool yn)
3117 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3119 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3120 if (!(*i)->hidden()) {
3121 (*i)->set_mute (yn, this);
3130 Session::n_diskstreams () const
3132 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
3135 for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3136 if (!(*i)->hidden()) {
3144 Session::foreach_diskstream (void (DiskStream::*func)(void))
3146 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
3147 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3148 if (!(*i)->hidden()) {
3155 Session::graph_reordered ()
3157 /* don't do this stuff if we are setting up connections
3158 from a set_state() call.
3161 if (_state_of_the_state & InitialConnecting) {
3165 RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3166 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3170 /* force all diskstreams to update their capture offset values to
3171 reflect any changes in latencies within the graph.
3174 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3175 (*i)->set_capture_offset ();
3180 Session::record_disenable_all ()
3182 record_enable_change_all (false);
3186 Session::record_enable_all ()
3188 record_enable_change_all (true);
3192 Session::record_enable_change_all (bool yn)
3194 RWLockMonitor lm1 (route_lock, false, __LINE__, __FILE__);
3196 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3199 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3200 at->set_record_enable (yn, this);
3204 /* since we don't keep rec-enable state, don't mark session dirty */
3208 Session::add_redirect (Redirect* redirect)
3212 PortInsert* port_insert;
3213 PluginInsert* plugin_insert;
3215 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3216 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3217 _port_inserts.insert (_port_inserts.begin(), port_insert);
3218 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3219 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3221 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3224 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3225 _sends.insert (_sends.begin(), send);
3227 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3231 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3237 Session::remove_redirect (Redirect* redirect)
3241 PortInsert* port_insert;
3242 PluginInsert* plugin_insert;
3244 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3245 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3246 _port_inserts.remove (port_insert);
3247 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3248 _plugin_inserts.remove (plugin_insert);
3250 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3253 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3254 _sends.remove (send);
3256 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3264 Session::available_capture_duration ()
3266 const double scale = 4096.0 / sizeof (Sample);
3268 if (_total_free_4k_blocks * scale > (double) max_frames) {
3272 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3276 Session::add_connection (ARDOUR::Connection* connection)
3279 LockMonitor (connection_lock, __LINE__, __FILE__);
3280 _connections.push_back (connection);
3283 ConnectionAdded (connection); /* EMIT SIGNAL */
3289 Session::remove_connection (ARDOUR::Connection* connection)
3291 bool removed = false;
3294 LockMonitor (connection_lock, __LINE__, __FILE__);
3295 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3297 if (i != _connections.end()) {
3298 _connections.erase (i);
3304 ConnectionRemoved (connection); /* EMIT SIGNAL */
3310 ARDOUR::Connection *
3311 Session::connection_by_name (string name) const
3313 LockMonitor lm (connection_lock, __LINE__, __FILE__);
3315 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3316 if ((*i)->name() == name) {
3325 Session::set_edit_mode (EditMode mode)
3330 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3332 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3333 (*i)->set_edit_mode (mode);
3338 ControlChanged (EditingMode); /* EMIT SIGNAL */
3342 Session::tempo_map_changed (Change ignored)
3349 Session::ensure_passthru_buffers (uint32_t howmany)
3351 while (howmany > _passthru_buffers.size()) {
3353 #ifdef NO_POSIX_MEMALIGN
3354 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3356 posix_memalign((void **)&p,16,current_block_size * 4);
3358 _passthru_buffers.push_back (p);
3362 #ifdef NO_POSIX_MEMALIGN
3363 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3365 posix_memalign((void **)&p,16,current_block_size * 4);
3367 memset (p, 0, sizeof (Sample) * current_block_size);
3368 _silent_buffers.push_back (p);
3372 #ifdef NO_POSIX_MEMALIGN
3373 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3375 posix_memalign((void **)&p,16,current_block_size * 4);
3377 memset (p, 0, sizeof (Sample) * current_block_size);
3378 _send_buffers.push_back (p);
3381 allocate_pan_automation_buffers (current_block_size, howmany, false);
3385 Session::next_send_name ()
3388 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3393 Session::next_insert_name ()
3396 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3400 /* Named Selection management */
3403 Session::named_selection_by_name (string name)
3405 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3406 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3407 if ((*i)->name == name) {
3415 Session::add_named_selection (NamedSelection* named_selection)
3418 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3419 named_selections.insert (named_selections.begin(), named_selection);
3424 NamedSelectionAdded (); /* EMIT SIGNAL */
3428 Session::remove_named_selection (NamedSelection* named_selection)
3430 bool removed = false;
3433 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3435 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3437 if (i != named_selections.end()) {
3439 named_selections.erase (i);
3446 NamedSelectionRemoved (); /* EMIT SIGNAL */
3451 Session::reset_native_file_format ()
3453 // jlc - WHY take routelock?
3454 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3455 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3457 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3458 (*i)->reset_write_sources (false);
3463 Session::route_name_unique (string n) const
3465 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3467 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3468 if ((*i)->name() == n) {
3477 Session::remove_file_source (FileSource& fs)
3479 return fs.move_to_trash (dead_sound_dir_name);
3483 Session::n_playlists () const
3485 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3486 return playlists.size();
3490 Session::set_solo_model (SoloModel sm)
3492 if (sm != _solo_model) {
3494 ControlChanged (SoloingModel);
3500 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3502 if (!force && howmany <= _npan_buffers) {
3506 if (_pan_automation_buffer) {
3508 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3509 delete [] _pan_automation_buffer[i];
3512 delete [] _pan_automation_buffer;
3515 _pan_automation_buffer = new pan_t*[howmany];
3517 for (uint32_t i = 0; i < howmany; ++i) {
3518 _pan_automation_buffer[i] = new pan_t[nframes];
3521 _npan_buffers = howmany;
3525 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3527 Stateful::add_instant_xml (node, dir);
3528 Config->add_instant_xml (node, get_user_ardour_path());
3532 Session::freeze (InterThreadInfo& itt)
3534 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3536 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3540 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3541 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3552 Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len, bool overwrite, vector<Source*>& srcs,
3553 InterThreadInfo& itt)
3557 FileSource* fsource;
3559 char buf[PATH_MAX+1];
3562 jack_nframes_t position;
3563 jack_nframes_t this_chunk;
3564 jack_nframes_t to_do;
3565 vector<Sample*> buffers;
3567 const jack_nframes_t chunk_size = (256 * 1024)/4;
3569 atomic_set (&processing_prohibited, 1);
3571 /* call tree *MUST* hold route_lock */
3573 if ((playlist = track.disk_stream().playlist()) == 0) {
3577 /* external redirects will be a problem */
3579 if (track.has_external_redirects()) {
3583 nchans = track.disk_stream().n_channels();
3585 dir = discover_best_sound_dir ();
3587 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3589 for (x = 0; x < 99999; ++x) {
3590 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3591 if (access (buf, F_OK) != 0) {
3597 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3602 fsource = new FileSource (buf, frame_rate(), false, Config->get_native_file_data_format());
3605 catch (failed_constructor& err) {
3606 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3610 srcs.push_back(fsource);
3613 /* XXX need to flush all redirects */
3618 /* create a set of reasonably-sized buffers */
3620 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3622 #ifdef NO_POSIX_MEMALIGN
3623 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3625 posix_memalign((void **)&b,16,chunk_size * 4);
3627 buffers.push_back (b);
3630 workbuf = new char[chunk_size * 4];
3632 while (to_do && !itt.cancel) {
3634 this_chunk = min (to_do, chunk_size);
3636 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3641 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3642 if ((*src)->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3647 start += this_chunk;
3648 to_do -= this_chunk;
3650 itt.progress = (float) (1.0 - ((double) to_do / len));
3659 xnow = localtime (&now);
3661 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3662 dynamic_cast<FileSource*>((*src))->update_header (position, *xnow, now);
3665 /* build peakfile for new source */
3667 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3668 dynamic_cast<FileSource*>(*src)->build_peaks ();
3676 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3677 dynamic_cast<FileSource*>(*src)->mark_for_remove ();
3682 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3690 atomic_set (&processing_prohibited, 0);
3698 Session::get_silent_buffers (uint32_t howmany)
3700 for (uint32_t i = 0; i < howmany; ++i) {
3701 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3703 return _silent_buffers;
3707 Session::ntracks () const
3710 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3712 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3713 if (dynamic_cast<AudioTrack*> (*i)) {
3722 Session::nbusses () const
3725 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3727 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3728 if (dynamic_cast<AudioTrack*> (*i) == 0) {
3737 Session::set_layer_model (LayerModel lm)
3739 if (lm != layer_model) {
3742 ControlChanged (LayeringModel);
3747 Session::set_xfade_model (CrossfadeModel xm)
3749 if (xm != xfade_model) {
3752 ControlChanged (CrossfadingModel);