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/sndfilesource.h>
52 #include <ardour/auditioner.h>
53 #include <ardour/recent_sessions.h>
54 #include <ardour/redirect.h>
55 #include <ardour/send.h>
56 #include <ardour/insert.h>
57 #include <ardour/connection.h>
58 #include <ardour/slave.h>
59 #include <ardour/tempo.h>
60 #include <ardour/audio_track.h>
61 #include <ardour/cycle_timer.h>
62 #include <ardour/named_selection.h>
63 #include <ardour/crossfade.h>
64 #include <ardour/playlist.h>
65 #include <ardour/click.h>
66 #include <ardour/timestamps.h>
71 using namespace ARDOUR;
72 //using namespace sigc;
74 const char* Session::_template_suffix = X_(".template");
75 const char* Session::_statefile_suffix = X_(".ardour");
76 const char* Session::_pending_suffix = X_(".pending");
77 const char* Session::sound_dir_name = X_("sounds");
78 const char* Session::peak_dir_name = X_("peaks");
79 const char* Session::dead_sound_dir_name = X_("dead_sounds");
81 Session::compute_peak_t Session::compute_peak = 0;
82 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
83 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
84 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
86 sigc::signal<int> Session::AskAboutPendingState;
89 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
96 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
97 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
103 /* check to see if it exists, and what it is */
105 if (stat (str.c_str(), &statbuf)) {
106 if (errno == ENOENT) {
109 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
117 /* it exists, so it must either be the name
118 of the directory, or the name of the statefile
122 if (S_ISDIR (statbuf.st_mode)) {
124 string::size_type slash = str.find_last_of ('/');
126 if (slash == string::npos) {
128 /* a subdirectory of cwd, so statefile should be ... */
134 tmp += _statefile_suffix;
138 if (stat (tmp.c_str(), &statbuf)) {
139 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
149 /* some directory someplace in the filesystem.
150 the snapshot name is the directory name
155 snapshot = str.substr (slash+1);
159 } else if (S_ISREG (statbuf.st_mode)) {
161 string::size_type slash = str.find_last_of ('/');
162 string::size_type suffix;
164 /* remove the suffix */
166 if (slash != string::npos) {
167 snapshot = str.substr (slash+1);
172 suffix = snapshot.find (_statefile_suffix);
174 if (suffix == string::npos) {
175 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
181 snapshot = snapshot.substr (0, suffix);
183 if (slash == string::npos) {
185 /* we must be in the directory where the
186 statefile lives. get it using cwd().
189 char cwd[PATH_MAX+1];
191 if (getcwd (cwd, sizeof (cwd)) == 0) {
192 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
201 /* full path to the statefile */
203 path = str.substr (0, slash);
208 /* what type of file is it? */
209 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
215 /* its the name of a new directory. get the name
219 string::size_type slash = str.find_last_of ('/');
221 if (slash == string::npos) {
223 /* no slash, just use the name, but clean it up */
225 path = legalize_for_path (str);
231 snapshot = str.substr (slash+1);
238 Session::Session (AudioEngine &eng,
240 string snapshot_name,
241 string* mix_template)
244 _mmc_port (default_mmc_port),
245 _mtc_port (default_mtc_port),
246 _midi_port (default_midi_port),
247 pending_events (2048),
248 midi_requests (128), // the size of this should match the midi request pool size
253 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
255 n_physical_outputs = _engine.n_physical_outputs();
256 n_physical_inputs = _engine.n_physical_inputs();
258 first_stage_init (fullpath, snapshot_name);
260 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
261 throw failed_constructor ();
264 if (second_stage_init (new_session)) {
265 throw failed_constructor ();
268 store_recent_sessions(_name, _path);
270 bool was_dirty = dirty();
272 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
275 DirtyChanged (); /* EMIT SIGNAL */
279 Session::Session (AudioEngine &eng,
281 string snapshot_name,
282 AutoConnectOption input_ac,
283 AutoConnectOption output_ac,
284 uint32_t control_out_channels,
285 uint32_t master_out_channels,
286 uint32_t requested_physical_in,
287 uint32_t requested_physical_out,
288 jack_nframes_t initial_length)
291 _mmc_port (default_mmc_port),
292 _mtc_port (default_mtc_port),
293 _midi_port (default_midi_port),
294 pending_events (2048),
301 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
303 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
304 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
306 first_stage_init (fullpath, snapshot_name);
308 if (create (new_session, 0, initial_length)) {
309 throw failed_constructor ();
312 if (control_out_channels) {
314 r = new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut);
319 if (master_out_channels) {
321 r = new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut);
325 /* prohibit auto-connect to master, because there isn't one */
326 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
329 input_auto_connect = input_ac;
330 output_auto_connect = output_ac;
332 if (second_stage_init (new_session)) {
333 throw failed_constructor ();
336 store_recent_sessions(_name, _path);
338 bool was_dirty = dirty ();
340 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
343 DirtyChanged (); /* EMIT SIGNAL */
349 /* if we got to here, leaving pending capture state around
353 remove_pending_capture_state ();
355 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
356 _engine.remove_session ();
358 going_away (); /* EMIT SIGNAL */
360 terminate_butler_thread ();
361 terminate_midi_thread ();
362 terminate_feedback ();
364 if (click_data && click_data != default_click) {
365 delete [] click_data;
368 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
369 delete [] click_emphasis_data;
383 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
387 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
391 #undef TRACK_DESTRUCTION
392 #ifdef TRACK_DESTRUCTION
393 cerr << "delete named selections\n";
394 #endif /* TRACK_DESTRUCTION */
395 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
396 NamedSelectionList::iterator tmp;
405 #ifdef TRACK_DESTRUCTION
406 cerr << "delete playlists\n";
407 #endif /* TRACK_DESTRUCTION */
408 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
409 PlaylistList::iterator tmp;
419 #ifdef TRACK_DESTRUCTION
420 cerr << "delete audio regions\n";
421 #endif /* TRACK_DESTRUCTION */
422 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
423 AudioRegionList::iterator tmp;
433 #ifdef TRACK_DESTRUCTION
434 cerr << "delete routes\n";
435 #endif /* TRACK_DESTRUCTION */
436 for (RouteList::iterator i = routes.begin(); i != routes.end(); ) {
437 RouteList::iterator tmp;
444 #ifdef TRACK_DESTRUCTION
445 cerr << "delete diskstreams\n";
446 #endif /* TRACK_DESTRUCTION */
447 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
448 DiskStreamList::iterator tmp;
458 #ifdef TRACK_DESTRUCTION
459 cerr << "delete sources\n";
460 #endif /* TRACK_DESTRUCTION */
461 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
462 SourceList::iterator tmp;
472 #ifdef TRACK_DESTRUCTION
473 cerr << "delete mix groups\n";
474 #endif /* TRACK_DESTRUCTION */
475 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
476 list<RouteGroup*>::iterator tmp;
486 #ifdef TRACK_DESTRUCTION
487 cerr << "delete edit groups\n";
488 #endif /* TRACK_DESTRUCTION */
489 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
490 list<RouteGroup*>::iterator tmp;
500 #ifdef TRACK_DESTRUCTION
501 cerr << "delete connections\n";
502 #endif /* TRACK_DESTRUCTION */
503 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
504 ConnectionList::iterator tmp;
514 if (butler_mixdown_buffer) {
515 delete [] butler_mixdown_buffer;
518 if (butler_gain_buffer) {
519 delete [] butler_gain_buffer;
522 Crossfade::set_buffer_size (0);
534 Session::set_worst_io_latencies (bool take_lock)
536 _worst_output_latency = 0;
537 _worst_input_latency = 0;
539 if (!_engine.connected()) {
544 route_lock.read_lock ();
547 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
548 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
549 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
553 route_lock.unlock ();
558 Session::when_engine_running ()
560 string first_physical_output;
562 /* we don't want to run execute this again */
564 first_time_running.disconnect ();
566 set_block_size (_engine.frames_per_cycle());
567 set_frame_rate (_engine.frame_rate());
569 /* every time we reconnect, recompute worst case output latencies */
571 _engine.Running.connect (sigc::bind (mem_fun (*this, &Session::set_worst_io_latencies), true));
573 if (synced_to_jack()) {
574 _engine.transport_stop ();
577 if (Config->get_jack_time_master()) {
578 _engine.transport_locate (_transport_frame);
586 _click_io = new ClickIO (*this, "click", 0, 0, -1, -1);
588 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
590 /* existing state for Click */
592 if (_click_io->set_state (*child->children().front()) == 0) {
594 _clicking = click_requested;
598 error << _("could not setup Click I/O") << endmsg;
604 /* default state for Click */
606 first_physical_output = _engine.get_nth_physical_output (0);
608 if (first_physical_output.length()) {
609 if (_click_io->add_output_port (first_physical_output, this)) {
610 // relax, even though its an error
612 _clicking = click_requested;
618 catch (failed_constructor& err) {
619 error << _("cannot setup Click I/O") << endmsg;
622 set_worst_io_latencies (true);
625 ControlChanged (Clicking); /* EMIT SIGNAL */
628 if (auditioner == 0) {
630 /* we delay creating the auditioner till now because
631 it makes its own connections to ports named
632 in the ARDOUR_RC config file. the engine has
633 to be running for this to work.
637 auditioner = new Auditioner (*this);
640 catch (failed_constructor& err) {
641 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
645 /* Create a set of Connection objects that map
646 to the physical outputs currently available
651 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
653 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
655 Connection* c = new OutputConnection (buf, true);
658 c->add_connection (0, _engine.get_nth_physical_output (np));
663 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
665 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
667 Connection* c = new InputConnection (buf, true);
670 c->add_connection (0, _engine.get_nth_physical_input (np));
677 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
679 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
681 Connection* c = new OutputConnection (buf, true);
685 c->add_connection (0, _engine.get_nth_physical_output (np));
686 c->add_connection (1, _engine.get_nth_physical_output (np+1));
691 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
693 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
695 Connection* c = new InputConnection (buf, true);
699 c->add_connection (0, _engine.get_nth_physical_input (np));
700 c->add_connection (1, _engine.get_nth_physical_input (np+1));
709 /* create master/control ports */
714 /* force the master to ignore any later call to this */
716 if (_master_out->pending_state_node) {
717 _master_out->ports_became_legal();
720 /* no panner resets till we are through */
722 _master_out->defer_pan_reset ();
724 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
725 if (_master_out->add_input_port ("", this)) {
726 error << _("cannot setup master inputs")
732 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
733 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
734 error << _("cannot setup master outputs")
741 _master_out->allow_pan_reset ();
745 Connection* c = new OutputConnection (_("Master Out"), true);
747 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
749 c->add_connection ((int) n, _master_out->input(n)->name());
756 /* catch up on send+insert cnts */
760 for (slist<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
763 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
764 if (id > insert_cnt) {
772 for (slist<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
775 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
782 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
784 /* hook us up to the engine */
786 _engine.set_session (this);
788 _state_of_the_state = Clean;
790 DirtyChanged (); /* EMIT SIGNAL */
794 Session::hookup_io ()
796 /* stop graph reordering notifications from
797 causing resorts, etc.
800 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
802 /* Tell all IO objects to create their ports */
809 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
810 if (_control_out->add_input_port ("", this)) {
811 error << _("cannot setup control inputs")
817 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
818 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
819 error << _("cannot set up master outputs")
827 /* Tell all IO objects to connect themselves together */
829 IO::enable_connecting ();
831 /* Now reset all panners */
833 IO::reset_panners ();
835 /* Anyone who cares about input state, wake up and do something */
837 IOConnectionsComplete (); /* EMIT SIGNAL */
839 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
841 /* now handle the whole enchilada as if it was one
847 /* update mixer solo state */
853 Session::playlist_length_changed (Playlist* pl)
855 /* we can't just increase end_location->end() if pl->get_maximum_extent()
856 if larger. if the playlist used to be the longest playlist,
857 and its now shorter, we have to decrease end_location->end(). hence,
858 we have to iterate over all diskstreams and check the
859 playlists currently in use.
865 Session::diskstream_playlist_changed (DiskStream* dstream)
869 if ((playlist = dstream->playlist()) != 0) {
870 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
873 /* see comment in playlist_length_changed () */
878 Session::record_enabling_legal () const
880 /* this used to be in here, but survey says.... we don't need to restrict it */
881 // if (record_status() == Recording) {
892 Session::set_auto_play (bool yn)
894 if (auto_play != yn) {
897 ControlChanged (AutoPlay);
902 Session::set_auto_return (bool yn)
904 if (auto_return != yn) {
907 ControlChanged (AutoReturn);
912 Session::set_crossfades_active (bool yn)
914 if (crossfades_active != yn) {
915 crossfades_active = yn;
917 ControlChanged (CrossFadesActive);
922 Session::set_recording_plugins (bool yn)
924 if (recording_plugins != yn) {
925 recording_plugins = yn;
927 ControlChanged (RecordingPlugins);
932 Session::set_auto_input (bool yn)
934 if (auto_input != yn) {
937 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
938 /* auto-input only makes a difference if we're rolling */
940 /* Even though this can called from RT context we are using
941 a non-tentative rwlock here, because the action must occur.
942 The rarity and short potential lock duration makes this "OK"
944 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
945 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
946 if ((*i)->record_enabled ()) {
947 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
948 (*i)->monitor_input (!auto_input);
954 ControlChanged (AutoInput);
959 Session::reset_input_monitor_state ()
961 if (transport_rolling()) {
962 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
963 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
964 if ((*i)->record_enabled ()) {
965 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
966 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
970 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
971 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
972 if ((*i)->record_enabled ()) {
973 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
974 (*i)->monitor_input (Config->get_use_hardware_monitoring());
982 Session::set_input_auto_connect (bool yn)
985 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
987 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
993 Session::get_input_auto_connect () const
995 return (input_auto_connect & AutoConnectPhysical);
999 Session::set_output_auto_connect (AutoConnectOption aco)
1001 output_auto_connect = aco;
1006 Session::auto_punch_start_changed (Location* location)
1008 replace_event (Event::PunchIn, location->start());
1010 if (get_record_enabled() && get_punch_in()) {
1011 /* capture start has been changed, so save new pending state */
1012 save_state ("", true);
1017 Session::auto_punch_end_changed (Location* location)
1019 jack_nframes_t when_to_stop = location->end();
1020 // when_to_stop += _worst_output_latency + _worst_input_latency;
1021 replace_event (Event::PunchOut, when_to_stop);
1025 Session::auto_punch_changed (Location* location)
1027 jack_nframes_t when_to_stop = location->end();
1029 replace_event (Event::PunchIn, location->start());
1030 //when_to_stop += _worst_output_latency + _worst_input_latency;
1031 replace_event (Event::PunchOut, when_to_stop);
1035 Session::auto_loop_changed (Location* location)
1037 replace_event (Event::AutoLoop, location->end(), location->start());
1039 if (transport_rolling() && get_auto_loop()) {
1041 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1043 if (_transport_frame > location->end()) {
1044 // relocate to beginning of loop
1045 clear_events (Event::LocateRoll);
1047 request_locate (location->start(), true);
1050 else if (seamless_loop && !loop_changing) {
1052 // schedule a locate-roll to refill the diskstreams at the
1053 // previous loop end
1054 loop_changing = true;
1056 if (location->end() > last_loopend) {
1057 clear_events (Event::LocateRoll);
1058 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1065 last_loopend = location->end();
1070 Session::set_auto_punch_location (Location* location)
1074 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1075 auto_punch_start_changed_connection.disconnect();
1076 auto_punch_end_changed_connection.disconnect();
1077 auto_punch_changed_connection.disconnect();
1078 existing->set_auto_punch (false, this);
1079 remove_event (existing->start(), Event::PunchIn);
1080 clear_events (Event::PunchOut);
1081 auto_punch_location_changed (0);
1086 if (location == 0) {
1090 if (location->end() <= location->start()) {
1091 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1095 auto_punch_start_changed_connection.disconnect();
1096 auto_punch_end_changed_connection.disconnect();
1097 auto_punch_changed_connection.disconnect();
1099 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1100 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1101 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1103 location->set_auto_punch (true, this);
1104 auto_punch_location_changed (location);
1108 Session::set_punch_in (bool yn)
1110 if (punch_in == yn) {
1116 if ((location = _locations.auto_punch_location()) != 0) {
1117 if ((punch_in = yn) == true) {
1118 replace_event (Event::PunchIn, location->start());
1120 remove_event (location->start(), Event::PunchIn);
1125 ControlChanged (PunchIn); /* EMIT SIGNAL */
1129 Session::set_punch_out (bool yn)
1131 if (punch_out == yn) {
1137 if ((location = _locations.auto_punch_location()) != 0) {
1138 if ((punch_out = yn) == true) {
1139 replace_event (Event::PunchOut, location->end());
1141 clear_events (Event::PunchOut);
1146 ControlChanged (PunchOut); /* EMIT SIGNAL */
1150 Session::set_auto_loop_location (Location* location)
1154 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1155 auto_loop_start_changed_connection.disconnect();
1156 auto_loop_end_changed_connection.disconnect();
1157 auto_loop_changed_connection.disconnect();
1158 existing->set_auto_loop (false, this);
1159 remove_event (existing->end(), Event::AutoLoop);
1160 auto_loop_location_changed (0);
1165 if (location == 0) {
1169 if (location->end() <= location->start()) {
1170 error << _("Session: you can't use a mark for auto loop") << endmsg;
1174 last_loopend = location->end();
1176 auto_loop_start_changed_connection.disconnect();
1177 auto_loop_end_changed_connection.disconnect();
1178 auto_loop_changed_connection.disconnect();
1180 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1181 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1182 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1184 location->set_auto_loop (true, this);
1185 auto_loop_location_changed (location);
1189 Session::locations_added (Location* ignored)
1195 Session::locations_changed ()
1197 _locations.apply (*this, &Session::handle_locations_changed);
1201 Session::handle_locations_changed (Locations::LocationList& locations)
1203 Locations::LocationList::iterator i;
1205 bool set_loop = false;
1206 bool set_punch = false;
1208 for (i = locations.begin(); i != locations.end(); ++i) {
1212 if (location->is_auto_punch()) {
1213 set_auto_punch_location (location);
1216 if (location->is_auto_loop()) {
1217 set_auto_loop_location (location);
1224 set_auto_loop_location (0);
1227 set_auto_punch_location (0);
1234 Session::enable_record ()
1236 /* XXX really atomic compare+swap here */
1237 if (atomic_read (&_record_status) != Recording) {
1238 atomic_set (&_record_status, Recording);
1239 _last_record_location = _transport_frame;
1240 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1242 if (Config->get_use_hardware_monitoring() && auto_input) {
1243 /* Even though this can be called from RT context we are using
1244 a non-tentative rwlock here, because the action must occur.
1245 The rarity and short potential lock duration makes this "OK"
1247 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1249 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1250 if ((*i)->record_enabled ()) {
1251 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
1252 (*i)->monitor_input (true);
1262 Session::disable_record ()
1264 if (atomic_read (&_record_status) != Disabled) {
1265 atomic_set (&_record_status, Disabled);
1266 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1268 if (Config->get_use_hardware_monitoring() && auto_input) {
1269 /* Even though this can be called from RT context we are using
1270 a non-tentative rwlock here, because the action must occur.
1271 The rarity and short potential lock duration makes this "OK"
1273 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1275 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1276 if ((*i)->record_enabled ()) {
1277 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1278 (*i)->monitor_input (false);
1284 remove_pending_capture_state ();
1290 Session::step_back_from_record ()
1292 atomic_set (&_record_status, Enabled);
1294 if (Config->get_use_hardware_monitoring()) {
1295 /* Even though this can be called from RT context we are using
1296 a non-tentative rwlock here, because the action must occur.
1297 The rarity and short potential lock duration makes this "OK"
1299 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1301 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1302 if (auto_input && (*i)->record_enabled ()) {
1303 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1304 (*i)->monitor_input (false);
1311 Session::maybe_enable_record ()
1313 atomic_set (&_record_status, Enabled);
1315 save_state ("", true);
1317 if (_transport_speed) {
1322 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1323 RecordEnabled (); /* EMIT SIGNAL */
1330 Session::audible_frame () const
1333 jack_nframes_t offset;
1336 /* the first of these two possible settings for "offset"
1337 mean that the audible frame is stationary until
1338 audio emerges from the latency compensation
1341 the second means that the audible frame is stationary
1342 until audio would emerge from a physical port
1343 in the absence of any plugin latency compensation
1346 offset = _worst_output_latency;
1348 if (offset > current_block_size) {
1349 offset -= current_block_size;
1351 /* XXX is this correct? if we have no external
1352 physical connections and everything is internal
1353 then surely this is zero? still, how
1354 likely is that anyway?
1356 offset = current_block_size;
1359 if (synced_to_jack()) {
1360 tf = _engine.transport_frame();
1362 tf = _transport_frame;
1365 if (_transport_speed == 0) {
1375 if (!non_realtime_work_pending()) {
1379 /* take latency into account */
1388 Session::set_frame_rate (jack_nframes_t frames_per_second)
1390 /** \fn void Session::set_frame_size(jack_nframes_t)
1391 the AudioEngine object that calls this guarantees
1392 that it will not be called while we are also in
1393 ::process(). Its fine to do things that block
1397 _current_frame_rate = frames_per_second;
1398 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1400 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1404 /* XXX need to reset/reinstantiate all LADSPA plugins */
1408 Session::set_block_size (jack_nframes_t nframes)
1410 /* the AudioEngine guarantees
1411 that it will not be called while we are also in
1412 ::process(). It is therefore fine to do things that block
1417 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1418 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1419 vector<Sample*>::iterator i;
1422 current_block_size = nframes;
1424 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1428 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1432 _passthru_buffers.clear ();
1433 _silent_buffers.clear ();
1435 ensure_passthru_buffers (np);
1437 if (_gain_automation_buffer) {
1438 delete [] _gain_automation_buffer;
1440 _gain_automation_buffer = new gain_t[nframes];
1442 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1444 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1445 (*i)->set_block_size (nframes);
1448 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1449 (*i)->set_block_size (nframes);
1452 set_worst_io_latencies (false);
1457 Session::set_default_fade (float steepness, float fade_msecs)
1460 jack_nframes_t fade_frames;
1462 /* Don't allow fade of less 1 frame */
1464 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1471 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1475 default_fade_msecs = fade_msecs;
1476 default_fade_steepness = steepness;
1479 // jlc, WTF is this!
1480 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1481 AudioRegion::set_default_fade (steepness, fade_frames);
1486 /* XXX have to do this at some point */
1487 /* foreach region using default fade, reset, then
1488 refill_all_diskstream_buffers ();
1493 struct RouteSorter {
1494 bool operator() (Route* r1, Route* r2) {
1495 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1497 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1500 if (r1->fed_by.empty()) {
1501 if (r2->fed_by.empty()) {
1502 /* no ardour-based connections inbound to either route. just use signal order */
1503 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1505 /* r2 has connections, r1 does not; run r1 early */
1509 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1516 trace_terminal (Route* r1, Route* rbase)
1520 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1521 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1525 /* make a copy of the existing list of routes that feed r1 */
1527 set<Route *> existing = r1->fed_by;
1529 /* for each route that feeds r1, recurse, marking it as feeding
1533 for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
1536 /* r2 is a route that feeds r1 which somehow feeds base. mark
1537 base as being fed by r2
1540 rbase->fed_by.insert (r2);
1544 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1548 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1552 /* now recurse, so that we can mark base as being fed by
1553 all routes that feed r2
1556 trace_terminal (r2, rbase);
1563 Session::resort_routes (void* src)
1565 /* don't do anything here with signals emitted
1566 by Routes while we are being destroyed.
1569 if (_state_of_the_state & Deletion) {
1573 /* Caller MUST hold the route_lock */
1575 RouteList::iterator i, j;
1577 for (i = routes.begin(); i != routes.end(); ++i) {
1579 (*i)->fed_by.clear ();
1581 for (j = routes.begin(); j != routes.end(); ++j) {
1583 /* although routes can feed themselves, it will
1584 cause an endless recursive descent if we
1585 detect it. so don't bother checking for
1593 if ((*j)->feeds (*i)) {
1594 (*i)->fed_by.insert (*j);
1599 for (i = routes.begin(); i != routes.end(); ++i) {
1600 trace_terminal (*i, *i);
1607 cerr << "finished route resort\n";
1609 for (i = routes.begin(); i != routes.end(); ++i) {
1610 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1618 Session::new_audio_track (int input_channels, int output_channels)
1621 char track_name[32];
1623 uint32_t channels_used = 0;
1625 uint32_t nphysical_in;
1626 uint32_t nphysical_out;
1628 /* count existing audio tracks */
1631 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1632 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1633 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1634 if (!(*i)->hidden()) {
1636 channels_used += (*i)->n_inputs();
1642 /* check for duplicate route names, since we might have pre-existing
1643 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1644 save, close,restart,add new route - first named route is now
1649 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1650 if (route_by_name (track_name) == 0) {
1655 } while (n < (UINT_MAX-1));
1657 if (input_auto_connect & AutoConnectPhysical) {
1658 nphysical_in = n_physical_inputs;
1663 if (output_auto_connect & AutoConnectPhysical) {
1664 nphysical_out = n_physical_outputs;
1670 track = new AudioTrack (*this, track_name);
1672 if (track->ensure_io (input_channels, output_channels, false, this)) {
1673 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1674 input_channels, output_channels)
1679 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1683 if (input_auto_connect & AutoConnectPhysical) {
1684 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1687 if (port.length() && track->connect_input (track->input (x), port, this)) {
1693 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1697 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1698 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1699 } else if (output_auto_connect & AutoConnectMaster) {
1701 port = _master_out->input (x%_master_out->n_inputs())->name();
1705 if (port.length() && track->connect_output (track->output (x), port, this)) {
1711 vector<string> cports;
1712 uint32_t ni = _control_out->n_inputs();
1714 for (n = 0; n < ni; ++n) {
1715 cports.push_back (_control_out->input(n)->name());
1718 track->set_control_outs (cports);
1721 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1725 track->set_remote_control_id (ntracks());
1728 catch (failed_constructor &err) {
1729 error << _("Session: could not create new audio track.") << endmsg;
1737 Session::new_audio_route (int input_channels, int output_channels)
1744 /* count existing audio busses */
1747 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1748 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1749 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1750 if (!(*i)->hidden()) {
1758 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1759 if (route_by_name (bus_name) == 0) {
1764 } while (n < (UINT_MAX-1));
1767 bus = new Route (*this, bus_name, -1, -1, -1, -1);
1769 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1770 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1771 input_channels, output_channels)
1775 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1779 if (input_auto_connect & AutoConnectPhysical) {
1780 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1783 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1788 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1792 if (output_auto_connect & AutoConnectPhysical) {
1793 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1794 } else if (output_auto_connect & AutoConnectMaster) {
1796 port = _master_out->input (x%_master_out->n_inputs())->name();
1800 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1806 vector<string> cports;
1807 uint32_t ni = _control_out->n_inputs();
1809 for (uint32_t n = 0; n < ni; ++n) {
1810 cports.push_back (_control_out->input(n)->name());
1812 bus->set_control_outs (cports);
1818 catch (failed_constructor &err) {
1819 error << _("Session: could not create new route.") << endmsg;
1827 Session::add_route (Route* route)
1830 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1831 routes.push_front (route);
1835 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1836 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1837 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1838 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1840 if (route->master()) {
1841 _master_out = route;
1844 if (route->control()) {
1845 _control_out = route;
1849 save_state (_current_snapshot_name);
1851 RouteAdded (route); /* EMIT SIGNAL */
1855 Session::add_diskstream (DiskStream* dstream)
1857 /* need to do this in case we're rolling at the time, to prevent false underruns */
1858 dstream->do_refill(0, 0);
1861 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1862 diskstreams.push_back (dstream);
1865 /* take a reference to the diskstream, preventing it from
1866 ever being deleted until the session itself goes away,
1867 or chooses to remove it for its own purposes.
1871 dstream->set_block_size (current_block_size);
1873 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1874 /* this will connect to future changes, and check the current length */
1875 diskstream_playlist_changed (dstream);
1877 dstream->prepare ();
1880 save_state (_current_snapshot_name);
1882 DiskStreamAdded (dstream); /* EMIT SIGNAL */
1886 Session::remove_route (Route& route)
1889 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1890 routes.remove (&route);
1892 /* deleting the master out seems like a dumb
1893 idea, but its more of a UI policy issue
1897 if (&route == _master_out) {
1901 if (&route == _control_out) {
1904 /* cancel control outs for all routes */
1906 vector<string> empty;
1908 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
1909 (*r)->set_control_outs (empty);
1913 update_route_solo_state ();
1917 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1921 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
1922 diskstreams.remove (&at->disk_stream());
1923 at->disk_stream().unref ();
1926 find_current_end ();
1929 update_latency_compensation (false, false);
1932 /* XXX should we disconnect from the Route's signals ? */
1934 save_state (_current_snapshot_name);
1940 Session::route_mute_changed (void* src)
1946 Session::route_solo_changed (void* src, Route* route)
1948 if (solo_update_disabled) {
1953 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1956 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
1958 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1960 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1964 /* don't mess with busses */
1966 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1972 /* don't mess with tracks */
1974 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1979 if ((*i) != route &&
1980 ((*i)->mix_group () == 0 ||
1981 (*i)->mix_group () != route->mix_group () ||
1982 !route->mix_group ()->is_active())) {
1984 if ((*i)->soloed()) {
1986 /* if its already soloed, and solo latching is enabled,
1987 then leave it as it is.
1990 if (_solo_latched) {
1997 solo_update_disabled = true;
1998 (*i)->set_solo (false, src);
1999 solo_update_disabled = false;
2003 bool something_soloed = false;
2004 bool same_thing_soloed = false;
2005 bool signal = false;
2007 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2008 if ((*i)->soloed()) {
2009 something_soloed = true;
2010 if (dynamic_cast<AudioTrack*>(*i)) {
2012 same_thing_soloed = true;
2017 same_thing_soloed = true;
2025 if (something_soloed != currently_soloing) {
2027 currently_soloing = something_soloed;
2030 modify_solo_mute (is_track, same_thing_soloed);
2033 SoloActive (currently_soloing);
2040 Session::set_solo_latched (bool yn)
2042 if (yn != _solo_latched) {
2045 ControlChanged (SoloLatch);
2050 Session::update_route_solo_state ()
2053 bool is_track = false;
2054 bool signal = false;
2056 /* caller must hold RouteLock */
2058 /* this is where we actually implement solo by changing
2059 the solo mute setting of each track.
2062 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2063 if ((*i)->soloed()) {
2065 if (dynamic_cast<AudioTrack*>(*i)) {
2072 if (mute != currently_soloing) {
2074 currently_soloing = mute;
2077 if (!is_track && !mute) {
2079 /* nothing is soloed */
2081 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2082 (*i)->set_solo_mute (false);
2092 modify_solo_mute (is_track, mute);
2095 SoloActive (currently_soloing);
2100 Session::modify_solo_mute (bool is_track, bool mute)
2102 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2106 /* only alter track solo mute */
2108 if (dynamic_cast<AudioTrack*>(*i)) {
2109 if ((*i)->soloed()) {
2110 (*i)->set_solo_mute (!mute);
2112 (*i)->set_solo_mute (mute);
2118 /* only alter bus solo mute */
2120 if (!dynamic_cast<AudioTrack*>(*i)) {
2122 if ((*i)->soloed()) {
2124 (*i)->set_solo_mute (false);
2128 /* don't mute master or control outs
2129 in response to another bus solo
2132 if ((*i) != _master_out &&
2133 (*i) != _control_out) {
2134 (*i)->set_solo_mute (mute);
2145 Session::catch_up_on_solo ()
2147 /* this is called after set_state() to catch the full solo
2148 state, which can't be correctly determined on a per-route
2149 basis, but needs the global overview that only the session
2152 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2153 update_route_solo_state();
2157 Session::route_by_name (string name)
2159 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2161 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2162 if ((*i)->name() == name) {
2171 Session::find_current_end ()
2173 jack_nframes_t max = 0;
2176 if (_state_of_the_state & Loading) {
2180 /* Don't take the diskstream lock. Caller must have other ways to
2184 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2185 Playlist* pl = (*i)->playlist();
2186 if ((me = pl->get_maximum_extent()) > max) {
2191 if (max > end_location->end()) {
2192 end_location->set_end (max);
2194 DurationChanged(); /* EMIT SIGNAL */
2199 Session::diskstream_by_name (string name)
2201 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2203 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2204 if ((*i)->name() == name) {
2213 Session::diskstream_by_id (id_t id)
2215 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2217 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2218 if ((*i)->id() == id) {
2226 /* AudioRegion management */
2229 Session::new_region_name (string old)
2231 string::size_type last_period;
2233 string::size_type len = old.length() + 64;
2236 if ((last_period = old.find_last_of ('.')) == string::npos) {
2238 /* no period present - add one explicitly */
2241 last_period = old.length() - 1;
2246 number = atoi (old.substr (last_period+1).c_str());
2250 while (number < (UINT_MAX-1)) {
2252 AudioRegionList::const_iterator i;
2257 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2260 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2261 if ((*i).second->name() == sbuf) {
2266 if (i == audio_regions.end()) {
2271 if (number != (UINT_MAX-1)) {
2275 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2280 Session::region_name (string& result, string base, bool newlevel) const
2287 LockMonitor lm (region_lock, __LINE__, __FILE__);
2289 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2297 /* XXX this is going to be slow. optimize me later */
2302 string::size_type pos;
2304 if ((pos = base.find_last_of ('-')) == string::npos) {
2305 pos = base.find_last_of ('.');
2308 /* pos may be npos, but then we just use entire base */
2310 subbase = base.substr (0, pos);
2313 bool name_taken = true;
2316 LockMonitor lm (region_lock, __LINE__, __FILE__);
2318 for (int n = 1; n < 5000; ++n) {
2321 snprintf (buf, sizeof (buf), ".%d", n);
2326 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2327 if ((*i).second->name() == result) {
2340 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2349 Session::add_region (Region* region)
2351 AudioRegion* ar = 0;
2352 AudioRegion* oar = 0;
2356 LockMonitor lm (region_lock, __LINE__, __FILE__);
2358 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2360 AudioRegionList::iterator x;
2362 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2364 oar = dynamic_cast<AudioRegion*> (x->second);
2366 if (ar->region_list_equivalent (*oar)) {
2371 if (x == audio_regions.end()) {
2373 pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry;
2375 entry.first = region->id();
2378 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2389 fatal << _("programming error: ")
2390 << X_("unknown region type passed to Session::add_region()")
2397 /* mark dirty because something has changed even if we didn't
2398 add the region to the region list.
2404 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2405 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2406 AudioRegionAdded (ar); /* EMIT SIGNAL */
2411 Session::region_changed (Change what_changed, Region* region)
2413 if (what_changed & Region::HiddenChanged) {
2414 /* relay hidden changes */
2415 RegionHiddenChange (region);
2420 Session::region_renamed (Region* region)
2422 add_region (region);
2426 Session::remove_region (Region* region)
2428 AudioRegionList::iterator i;
2429 AudioRegion* ar = 0;
2430 bool removed = false;
2433 LockMonitor lm (region_lock, __LINE__, __FILE__);
2435 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2436 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2437 audio_regions.erase (i);
2441 fatal << _("programming error: ")
2442 << X_("unknown region type passed to Session::remove_region()")
2448 /* mark dirty because something has changed even if we didn't
2449 remove the region from the region list.
2455 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2460 Session::find_whole_file_parent (AudioRegion& child)
2462 AudioRegionList::iterator i;
2463 AudioRegion* region;
2464 LockMonitor lm (region_lock, __LINE__, __FILE__);
2466 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2468 region = (*i).second;
2470 if (region->whole_file()) {
2472 if (child.source_equivalent (*region)) {
2482 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2484 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2488 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2492 pl->get_region_list_equivalent_regions (region, result);
2497 Session::destroy_region (Region* region)
2499 AudioRegion* aregion;
2501 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2505 if (aregion->playlist()) {
2506 aregion->playlist()->destroy_region (region);
2509 vector<Source*> srcs;
2511 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2512 srcs.push_back (&aregion->source (n));
2515 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2517 if ((*i)->use_cnt() == 0) {
2518 (*i)->mark_for_remove ();
2527 Session::destroy_regions (list<Region*> regions)
2529 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2530 destroy_region (*i);
2536 Session::remove_last_capture ()
2540 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2542 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2543 list<Region*>& l = (*i)->last_capture_regions();
2546 r.insert (r.end(), l.begin(), l.end());
2551 destroy_regions (r);
2556 Session::remove_region_from_region_list (Region& r)
2562 /* Source Management */
2565 Session::add_source (Source* source)
2567 pair<SourceList::key_type, SourceList::mapped_type> entry;
2570 LockMonitor lm (source_lock, __LINE__, __FILE__);
2571 entry.first = source->id();
2572 entry.second = source;
2573 sources.insert (entry);
2576 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2579 SourceAdded (source); /* EMIT SIGNAL */
2583 Session::remove_source (Source* source)
2585 SourceList::iterator i;
2588 LockMonitor lm (source_lock, __LINE__, __FILE__);
2590 if ((i = sources.find (source->id())) != sources.end()) {
2595 if (!_state_of_the_state & InCleanup) {
2597 /* save state so we don't end up with a session file
2598 referring to non-existent sources.
2601 save_state (_current_snapshot_name);
2604 SourceRemoved(source); /* EMIT SIGNAL */
2608 Session::get_source (ARDOUR::id_t id)
2610 LockMonitor lm (source_lock, __LINE__, __FILE__);
2611 SourceList::iterator i;
2614 if ((i = sources.find (id)) != sources.end()) {
2615 source = (*i).second;
2622 Session::create_file_source (DiskStream& ds, int32_t chan)
2626 char buf[PATH_MAX+1];
2627 const uint32_t limit = 10000;
2631 legalized = legalize_for_path (ds.name());
2633 /* find a "version" of the file name that doesn't exist in
2634 any of the possible directories.
2637 for (cnt = 1; cnt <= limit; ++cnt) {
2639 vector<space_and_path>::iterator i;
2640 uint32_t existing = 0;
2642 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2645 spath += sound_dir_name;
2649 if (ds.n_channels() < 2) {
2650 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2651 } else if (ds.n_channels() == 2) {
2653 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2655 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2657 } else if (ds.n_channels() < 26) {
2658 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2660 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2663 if (access (buf, F_OK) == 0) {
2668 if (existing == 0) {
2674 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, ds.name()) << endmsg;
2675 throw failed_constructor();
2678 /* we now have a unique name for the file, but figure out where to
2684 spath = discover_best_sound_dir ();
2686 string::size_type pos = foo.find_last_of ('/');
2688 if (pos == string::npos) {
2691 spath += foo.substr (pos + 1);
2694 /* this might throw failed_constructor(), which is OK */
2696 return new FileSource (spath, frame_rate());
2699 /* Playlist management */
2702 Session::get_playlist (string name)
2706 if ((ret = playlist_by_name (name)) == 0) {
2707 ret = new AudioPlaylist (*this, name);
2714 Session::playlist_by_name (string name)
2716 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2717 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2718 if ((*i)->name() == name) {
2722 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2723 if ((*i)->name() == name) {
2731 Session::add_playlist (Playlist* playlist)
2733 if (playlist->hidden()) {
2738 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2739 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2740 playlists.insert (playlists.begin(), playlist);
2742 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2743 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2749 PlaylistAdded (playlist); /* EMIT SIGNAL */
2753 Session::track_playlist (Playlist* pl, bool inuse)
2755 PlaylistList::iterator x;
2758 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2761 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2763 unused_playlists.insert (pl);
2765 if ((x = playlists.find (pl)) != playlists.end()) {
2766 playlists.erase (x);
2771 //cerr << "shifting playlist to used: " << pl->name() << endl;
2773 playlists.insert (pl);
2775 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2776 unused_playlists.erase (x);
2783 Session::remove_playlist (Playlist* playlist)
2785 if (_state_of_the_state & Deletion) {
2790 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2791 // cerr << "removing playlist: " << playlist->name() << endl;
2793 PlaylistList::iterator i;
2795 i = find (playlists.begin(), playlists.end(), playlist);
2797 if (i != playlists.end()) {
2798 playlists.erase (i);
2801 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
2802 if (i != unused_playlists.end()) {
2803 unused_playlists.erase (i);
2810 PlaylistRemoved (playlist); /* EMIT SIGNAL */
2814 Session::set_audition (AudioRegion* r)
2816 pending_audition_region = r;
2817 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
2818 schedule_butler_transport_work ();
2822 Session::non_realtime_set_audition ()
2824 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
2825 auditioner->audition_current_playlist ();
2826 } else if (pending_audition_region) {
2827 auditioner->audition_region (*pending_audition_region);
2829 pending_audition_region = 0;
2830 AuditionActive (true); /* EMIT SIGNAL */
2834 Session::audition_playlist ()
2836 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
2837 ev->set_ptr ((void*) 0xfeedface);
2842 Session::audition_region (AudioRegion& r)
2844 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
2850 Session::cancel_audition ()
2852 if (auditioner->active()) {
2853 auditioner->cancel_audition ();
2854 AuditionActive (false); /* EMIT SIGNAL */
2859 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
2861 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
2865 Session::remove_empty_sounds ()
2868 PathScanner scanner;
2873 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
2875 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
2877 if (FileSource::is_empty (*(*i))) {
2879 unlink ((*i)->c_str());
2881 string peak_path = peak_path_from_audio_path (**i);
2882 unlink (peak_path.c_str());
2888 delete possible_audiofiles;
2892 Session::is_auditioning () const
2894 /* can be called before we have an auditioner object */
2896 return auditioner->active();
2904 Session::peak_path_from_audio_path (string audio_path)
2906 /* XXX hardly bombproof! fix me */
2910 res = PBD::dirname (audio_path);
2911 res = PBD::dirname (res);
2913 res += peak_dir_name;
2915 res += PBD::basename_nosuffix (audio_path);
2922 Session::old_peak_path_from_audio_path (string audio_path)
2924 /* This is a hangover from when audio and peak files
2925 lived in the same directory. We need it to to
2926 be able to open old sessions.
2929 /* XXX hardly bombproof! fix me */
2931 string res = audio_path.substr (0, audio_path.find_last_of ('.'));
2937 Session::set_all_solo (bool yn)
2940 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2942 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2943 if (!(*i)->hidden()) {
2944 (*i)->set_solo (yn, this);
2953 Session::set_all_mute (bool yn)
2956 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2958 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2959 if (!(*i)->hidden()) {
2960 (*i)->set_mute (yn, this);
2969 Session::n_diskstreams () const
2971 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2974 for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2975 if (!(*i)->hidden()) {
2983 Session::foreach_diskstream (void (DiskStream::*func)(void))
2985 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2986 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2987 if (!(*i)->hidden()) {
2994 Session::graph_reordered ()
2996 /* don't do this stuff if we are setting up connections
2997 from a set_state() call.
3000 if (_state_of_the_state & InitialConnecting) {
3004 RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3005 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3009 /* force all diskstreams to update their capture offset values to
3010 reflect any changes in latencies within the graph.
3013 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3014 (*i)->set_capture_offset ();
3019 Session::record_disenable_all ()
3021 record_enable_change_all (false);
3025 Session::record_enable_all ()
3027 record_enable_change_all (true);
3031 Session::record_enable_change_all (bool yn)
3033 RWLockMonitor lm1 (route_lock, false, __LINE__, __FILE__);
3035 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3038 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3039 at->set_record_enable (yn, this);
3043 /* since we don't keep rec-enable state, don't mark session dirty */
3047 Session::add_redirect (Redirect* redirect)
3051 PortInsert* port_insert;
3052 PluginInsert* plugin_insert;
3054 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3055 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3056 _port_inserts.insert (_port_inserts.begin(), port_insert);
3057 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3058 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3060 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3063 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3064 _sends.insert (_sends.begin(), send);
3066 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3070 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3076 Session::remove_redirect (Redirect* redirect)
3080 PortInsert* port_insert;
3081 PluginInsert* plugin_insert;
3083 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3084 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3085 _port_inserts.remove (port_insert);
3086 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3087 _plugin_inserts.remove (plugin_insert);
3089 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3092 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3093 _sends.remove (send);
3095 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3103 Session::available_capture_duration ()
3105 const double scale = 4096.0 / sizeof (Sample);
3107 if (_total_free_4k_blocks * scale > (double) max_frames) {
3111 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3115 Session::add_connection (ARDOUR::Connection* connection)
3118 LockMonitor (connection_lock, __LINE__, __FILE__);
3119 _connections.push_back (connection);
3122 ConnectionAdded (connection); /* EMIT SIGNAL */
3128 Session::remove_connection (ARDOUR::Connection* connection)
3130 bool removed = false;
3133 LockMonitor (connection_lock, __LINE__, __FILE__);
3134 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3136 if (i != _connections.end()) {
3137 _connections.erase (i);
3143 ConnectionRemoved (connection); /* EMIT SIGNAL */
3149 ARDOUR::Connection *
3150 Session::connection_by_name (string name) const
3152 LockMonitor lm (connection_lock, __LINE__, __FILE__);
3154 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3155 if ((*i)->name() == name) {
3164 Session::set_edit_mode (EditMode mode)
3169 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3171 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3172 (*i)->set_edit_mode (mode);
3177 ControlChanged (EditingMode); /* EMIT SIGNAL */
3181 Session::tempo_map_changed (Change ignored)
3188 Session::ensure_passthru_buffers (uint32_t howmany)
3190 while (howmany > _passthru_buffers.size()) {
3192 #ifdef NO_POSIX_MEMALIGN
3193 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3195 posix_memalign((void **)&p,16,current_block_size * 4);
3197 _passthru_buffers.push_back (p);
3201 #ifdef NO_POSIX_MEMALIGN
3202 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3204 posix_memalign((void **)&p,16,current_block_size * 4);
3206 memset (p, 0, sizeof (Sample) * current_block_size);
3207 _silent_buffers.push_back (p);
3210 allocate_pan_automation_buffers (current_block_size, howmany, false);
3214 Session::next_send_name ()
3217 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3222 Session::next_insert_name ()
3225 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3229 /* Named Selection management */
3232 Session::named_selection_by_name (string name)
3234 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3235 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3236 if ((*i)->name == name) {
3244 Session::add_named_selection (NamedSelection* named_selection)
3247 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3248 named_selections.insert (named_selections.begin(), named_selection);
3253 NamedSelectionAdded (); /* EMIT SIGNAL */
3257 Session::remove_named_selection (NamedSelection* named_selection)
3259 bool removed = false;
3262 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3264 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3266 if (i != named_selections.end()) {
3268 named_selections.erase (i);
3275 NamedSelectionRemoved (); /* EMIT SIGNAL */
3280 Session::reset_native_file_format ()
3282 // jlc - WHY take routelock?
3283 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3284 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3286 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3287 (*i)->reset_write_sources (false);
3292 Session::route_name_unique (string n) const
3294 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3296 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3297 if ((*i)->name() == n) {
3306 Session::remove_file_source (FileSource& fs)
3308 return fs.move_to_trash (dead_sound_dir_name);
3312 Session::n_playlists () const
3314 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3315 return playlists.size();
3319 Session::set_solo_model (SoloModel sm)
3321 if (sm != _solo_model) {
3323 ControlChanged (SoloingModel);
3329 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3331 if (!force && howmany <= _npan_buffers) {
3335 if (_pan_automation_buffer) {
3337 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3338 delete [] _pan_automation_buffer[i];
3341 delete [] _pan_automation_buffer;
3344 _pan_automation_buffer = new pan_t*[howmany];
3346 for (uint32_t i = 0; i < howmany; ++i) {
3347 _pan_automation_buffer[i] = new pan_t[nframes];
3350 _npan_buffers = howmany;
3354 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3356 Stateful::add_instant_xml (node, dir);
3357 Config->add_instant_xml (node, Config->get_user_ardour_path());
3361 Session::freeze (InterThreadInfo& itt)
3363 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3365 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3369 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3370 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3381 Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len, bool overwrite, vector<Source*>& srcs,
3382 InterThreadInfo& itt)
3386 FileSource* fsource;
3388 char buf[PATH_MAX+1];
3391 jack_nframes_t position;
3392 jack_nframes_t this_chunk;
3393 jack_nframes_t to_do;
3394 vector<Sample*> buffers;
3395 const jack_nframes_t chunk_size = (256 * 1024)/4;
3397 atomic_set (&processing_prohibited, 1);
3399 /* call tree *MUST* hold route_lock */
3401 if ((playlist = track.disk_stream().playlist()) == 0) {
3405 /* external redirects will be a problem */
3407 if (track.has_external_redirects()) {
3411 nchans = track.disk_stream().n_channels();
3413 dir = discover_best_sound_dir ();
3415 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3417 for (x = 0; x < 99999; ++x) {
3418 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3419 if (access (buf, F_OK) != 0) {
3425 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3430 fsource = new FileSource (buf, frame_rate());
3433 catch (failed_constructor& err) {
3434 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3438 srcs.push_back(fsource);
3441 /* XXX need to flush all redirects */
3446 /* create a set of reasonably-sized buffers */
3448 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3450 #ifdef NO_POSIX_MEMALIGN
3451 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3453 posix_memalign((void **)&b,16,chunk_size * 4);
3455 buffers.push_back (b);
3458 while (to_do && !itt.cancel) {
3460 this_chunk = min (to_do, chunk_size);
3462 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3467 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3468 if ((*src)->write (buffers[n], this_chunk) != this_chunk) {
3473 start += this_chunk;
3474 to_do -= this_chunk;
3476 itt.progress = (float) (1.0 - ((double) to_do / len));
3485 xnow = localtime (&now);
3487 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3488 dynamic_cast<FileSource*>((*src))->update_header (position, *xnow, now);
3491 /* build peakfile for new source */
3493 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3494 dynamic_cast<FileSource*>(*src)->build_peaks ();
3502 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3503 dynamic_cast<FileSource*>(*src)->mark_for_remove ();
3508 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3512 atomic_set (&processing_prohibited, 0);
3520 Session::get_silent_buffers (uint32_t howmany)
3522 for (uint32_t i = 0; i < howmany; ++i) {
3523 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3525 return _silent_buffers;
3529 Session::ntracks () const
3532 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3534 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3535 if (dynamic_cast<AudioTrack*> (*i)) {
3544 Session::nbusses () const
3547 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3549 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3550 if (dynamic_cast<AudioTrack*> (*i) == 0) {
3559 Session::set_layer_model (LayerModel lm)
3561 if (lm != layer_model) {
3564 ControlChanged (LayeringModel);
3569 Session::set_xfade_model (CrossfadeModel xm)
3571 if (xm != xfade_model) {
3574 ControlChanged (CrossfadingModel);