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::peak_dir_name = X_("peaks");
80 const char* Session::dead_sound_dir_name = X_("dead_sounds");
82 Session::compute_peak_t Session::compute_peak = 0;
83 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
84 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
85 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
87 sigc::signal<int> Session::AskAboutPendingState;
90 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
97 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
98 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
104 /* check to see if it exists, and what it is */
106 if (stat (str.c_str(), &statbuf)) {
107 if (errno == ENOENT) {
110 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
118 /* it exists, so it must either be the name
119 of the directory, or the name of the statefile
123 if (S_ISDIR (statbuf.st_mode)) {
125 string::size_type slash = str.find_last_of ('/');
127 if (slash == string::npos) {
129 /* a subdirectory of cwd, so statefile should be ... */
135 tmp += _statefile_suffix;
139 if (stat (tmp.c_str(), &statbuf)) {
140 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
150 /* some directory someplace in the filesystem.
151 the snapshot name is the directory name
156 snapshot = str.substr (slash+1);
160 } else if (S_ISREG (statbuf.st_mode)) {
162 string::size_type slash = str.find_last_of ('/');
163 string::size_type suffix;
165 /* remove the suffix */
167 if (slash != string::npos) {
168 snapshot = str.substr (slash+1);
173 suffix = snapshot.find (_statefile_suffix);
175 if (suffix == string::npos) {
176 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
182 snapshot = snapshot.substr (0, suffix);
184 if (slash == string::npos) {
186 /* we must be in the directory where the
187 statefile lives. get it using cwd().
190 char cwd[PATH_MAX+1];
192 if (getcwd (cwd, sizeof (cwd)) == 0) {
193 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
202 /* full path to the statefile */
204 path = str.substr (0, slash);
209 /* what type of file is it? */
210 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
216 /* its the name of a new directory. get the name
220 string::size_type slash = str.find_last_of ('/');
222 if (slash == string::npos) {
224 /* no slash, just use the name, but clean it up */
226 path = legalize_for_path (str);
232 snapshot = str.substr (slash+1);
239 Session::Session (AudioEngine &eng,
241 string snapshot_name,
242 string* mix_template)
245 _mmc_port (default_mmc_port),
246 _mtc_port (default_mtc_port),
247 _midi_port (default_midi_port),
248 pending_events (2048),
249 midi_requests (128), // the size of this should match the midi request pool size
254 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
256 n_physical_outputs = _engine.n_physical_outputs();
257 n_physical_inputs = _engine.n_physical_inputs();
259 first_stage_init (fullpath, snapshot_name);
261 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
262 throw failed_constructor ();
265 if (second_stage_init (new_session)) {
266 throw failed_constructor ();
269 store_recent_sessions(_name, _path);
271 bool was_dirty = dirty();
273 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
276 DirtyChanged (); /* EMIT SIGNAL */
280 Session::Session (AudioEngine &eng,
282 string snapshot_name,
283 AutoConnectOption input_ac,
284 AutoConnectOption output_ac,
285 uint32_t control_out_channels,
286 uint32_t master_out_channels,
287 uint32_t requested_physical_in,
288 uint32_t requested_physical_out,
289 jack_nframes_t initial_length)
292 _mmc_port (default_mmc_port),
293 _mtc_port (default_mtc_port),
294 _midi_port (default_midi_port),
295 pending_events (2048),
302 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
304 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
305 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
307 first_stage_init (fullpath, snapshot_name);
309 if (create (new_session, 0, initial_length)) {
310 throw failed_constructor ();
313 if (control_out_channels) {
315 r = new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut);
320 if (master_out_channels) {
322 r = new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut);
326 /* prohibit auto-connect to master, because there isn't one */
327 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
330 input_auto_connect = input_ac;
331 output_auto_connect = output_ac;
333 if (second_stage_init (new_session)) {
334 throw failed_constructor ();
337 store_recent_sessions(_name, _path);
339 bool was_dirty = dirty ();
341 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
344 DirtyChanged (); /* EMIT SIGNAL */
350 /* if we got to here, leaving pending capture state around
354 remove_pending_capture_state ();
356 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
357 _engine.remove_session ();
359 going_away (); /* EMIT SIGNAL */
361 terminate_butler_thread ();
362 terminate_midi_thread ();
363 terminate_feedback ();
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 #undef TRACK_DESTRUCTION
393 #ifdef TRACK_DESTRUCTION
394 cerr << "delete named selections\n";
395 #endif /* TRACK_DESTRUCTION */
396 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
397 NamedSelectionList::iterator tmp;
406 #ifdef TRACK_DESTRUCTION
407 cerr << "delete playlists\n";
408 #endif /* TRACK_DESTRUCTION */
409 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
410 PlaylistList::iterator tmp;
420 #ifdef TRACK_DESTRUCTION
421 cerr << "delete audio regions\n";
422 #endif /* TRACK_DESTRUCTION */
423 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
424 AudioRegionList::iterator tmp;
434 #ifdef TRACK_DESTRUCTION
435 cerr << "delete routes\n";
436 #endif /* TRACK_DESTRUCTION */
437 for (RouteList::iterator i = routes.begin(); i != routes.end(); ) {
438 RouteList::iterator tmp;
445 #ifdef TRACK_DESTRUCTION
446 cerr << "delete diskstreams\n";
447 #endif /* TRACK_DESTRUCTION */
448 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
449 DiskStreamList::iterator tmp;
459 #ifdef TRACK_DESTRUCTION
460 cerr << "delete sources\n";
461 #endif /* TRACK_DESTRUCTION */
462 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
463 SourceList::iterator tmp;
473 #ifdef TRACK_DESTRUCTION
474 cerr << "delete mix groups\n";
475 #endif /* TRACK_DESTRUCTION */
476 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
477 list<RouteGroup*>::iterator tmp;
487 #ifdef TRACK_DESTRUCTION
488 cerr << "delete edit groups\n";
489 #endif /* TRACK_DESTRUCTION */
490 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
491 list<RouteGroup*>::iterator tmp;
501 #ifdef TRACK_DESTRUCTION
502 cerr << "delete connections\n";
503 #endif /* TRACK_DESTRUCTION */
504 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
505 ConnectionList::iterator tmp;
515 if (butler_mixdown_buffer) {
516 delete [] butler_mixdown_buffer;
519 if (butler_gain_buffer) {
520 delete [] butler_gain_buffer;
523 Crossfade::set_buffer_size (0);
535 Session::set_worst_io_latencies (bool take_lock)
537 _worst_output_latency = 0;
538 _worst_input_latency = 0;
540 if (!_engine.connected()) {
545 route_lock.read_lock ();
548 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
549 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
550 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
554 route_lock.unlock ();
559 Session::when_engine_running ()
561 string first_physical_output;
563 /* we don't want to run execute this again */
565 first_time_running.disconnect ();
567 set_block_size (_engine.frames_per_cycle());
568 set_frame_rate (_engine.frame_rate());
570 /* every time we reconnect, recompute worst case output latencies */
572 _engine.Running.connect (sigc::bind (mem_fun (*this, &Session::set_worst_io_latencies), true));
574 if (synced_to_jack()) {
575 _engine.transport_stop ();
578 if (Config->get_jack_time_master()) {
579 _engine.transport_locate (_transport_frame);
587 _click_io = new ClickIO (*this, "click", 0, 0, -1, -1);
589 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
591 /* existing state for Click */
593 if (_click_io->set_state (*child->children().front()) == 0) {
595 _clicking = click_requested;
599 error << _("could not setup Click I/O") << endmsg;
605 /* default state for Click */
607 first_physical_output = _engine.get_nth_physical_output (0);
609 if (first_physical_output.length()) {
610 if (_click_io->add_output_port (first_physical_output, this)) {
611 // relax, even though its an error
613 _clicking = click_requested;
619 catch (failed_constructor& err) {
620 error << _("cannot setup Click I/O") << endmsg;
623 set_worst_io_latencies (true);
626 ControlChanged (Clicking); /* EMIT SIGNAL */
629 if (auditioner == 0) {
631 /* we delay creating the auditioner till now because
632 it makes its own connections to ports named
633 in the ARDOUR_RC config file. the engine has
634 to be running for this to work.
638 auditioner = new Auditioner (*this);
641 catch (failed_constructor& err) {
642 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
646 /* Create a set of Connection objects that map
647 to the physical outputs currently available
652 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
654 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
656 Connection* c = new OutputConnection (buf, true);
659 c->add_connection (0, _engine.get_nth_physical_output (np));
664 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
666 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
668 Connection* c = new InputConnection (buf, true);
671 c->add_connection (0, _engine.get_nth_physical_input (np));
678 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
680 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
682 Connection* c = new OutputConnection (buf, true);
686 c->add_connection (0, _engine.get_nth_physical_output (np));
687 c->add_connection (1, _engine.get_nth_physical_output (np+1));
692 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
694 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
696 Connection* c = new InputConnection (buf, true);
700 c->add_connection (0, _engine.get_nth_physical_input (np));
701 c->add_connection (1, _engine.get_nth_physical_input (np+1));
710 /* create master/control ports */
715 /* force the master to ignore any later call to this */
717 if (_master_out->pending_state_node) {
718 _master_out->ports_became_legal();
721 /* no panner resets till we are through */
723 _master_out->defer_pan_reset ();
725 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
726 if (_master_out->add_input_port ("", this)) {
727 error << _("cannot setup master inputs")
733 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
734 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
735 error << _("cannot setup master outputs")
742 _master_out->allow_pan_reset ();
746 Connection* c = new OutputConnection (_("Master Out"), true);
748 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
750 c->add_connection ((int) n, _master_out->input(n)->name());
757 /* catch up on send+insert cnts */
761 for (slist<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
764 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
765 if (id > insert_cnt) {
773 for (slist<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
776 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
783 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
785 /* hook us up to the engine */
787 _engine.set_session (this);
789 _state_of_the_state = Clean;
791 DirtyChanged (); /* EMIT SIGNAL */
795 Session::hookup_io ()
797 /* stop graph reordering notifications from
798 causing resorts, etc.
801 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
803 /* Tell all IO objects to create their ports */
810 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
811 if (_control_out->add_input_port ("", this)) {
812 error << _("cannot setup control inputs")
818 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
819 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
820 error << _("cannot set up master outputs")
828 /* Tell all IO objects to connect themselves together */
830 IO::enable_connecting ();
832 /* Now reset all panners */
834 IO::reset_panners ();
836 /* Anyone who cares about input state, wake up and do something */
838 IOConnectionsComplete (); /* EMIT SIGNAL */
840 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
842 /* now handle the whole enchilada as if it was one
848 /* update mixer solo state */
854 Session::playlist_length_changed (Playlist* pl)
856 /* we can't just increase end_location->end() if pl->get_maximum_extent()
857 if larger. if the playlist used to be the longest playlist,
858 and its now shorter, we have to decrease end_location->end(). hence,
859 we have to iterate over all diskstreams and check the
860 playlists currently in use.
866 Session::diskstream_playlist_changed (DiskStream* dstream)
870 if ((playlist = dstream->playlist()) != 0) {
871 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
874 /* see comment in playlist_length_changed () */
879 Session::record_enabling_legal () const
881 /* this used to be in here, but survey says.... we don't need to restrict it */
882 // if (record_status() == Recording) {
893 Session::set_auto_play (bool yn)
895 if (auto_play != yn) {
898 ControlChanged (AutoPlay);
903 Session::set_auto_return (bool yn)
905 if (auto_return != yn) {
908 ControlChanged (AutoReturn);
913 Session::set_crossfades_active (bool yn)
915 if (crossfades_active != yn) {
916 crossfades_active = yn;
918 ControlChanged (CrossFadesActive);
923 Session::set_recording_plugins (bool yn)
925 if (recording_plugins != yn) {
926 recording_plugins = yn;
928 ControlChanged (RecordingPlugins);
933 Session::set_auto_input (bool yn)
935 if (auto_input != yn) {
938 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
939 /* auto-input only makes a difference if we're rolling */
941 /* Even though this can called from RT context we are using
942 a non-tentative rwlock here, because the action must occur.
943 The rarity and short potential lock duration makes this "OK"
945 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
946 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
947 if ((*i)->record_enabled ()) {
948 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
949 (*i)->monitor_input (!auto_input);
955 ControlChanged (AutoInput);
960 Session::reset_input_monitor_state ()
962 if (transport_rolling()) {
963 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
964 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
965 if ((*i)->record_enabled ()) {
966 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
967 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
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());
983 Session::set_input_auto_connect (bool yn)
986 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
988 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
994 Session::get_input_auto_connect () const
996 return (input_auto_connect & AutoConnectPhysical);
1000 Session::set_output_auto_connect (AutoConnectOption aco)
1002 output_auto_connect = aco;
1007 Session::auto_punch_start_changed (Location* location)
1009 replace_event (Event::PunchIn, location->start());
1011 if (get_record_enabled() && get_punch_in()) {
1012 /* capture start has been changed, so save new pending state */
1013 save_state ("", true);
1018 Session::auto_punch_end_changed (Location* location)
1020 jack_nframes_t when_to_stop = location->end();
1021 // when_to_stop += _worst_output_latency + _worst_input_latency;
1022 replace_event (Event::PunchOut, when_to_stop);
1026 Session::auto_punch_changed (Location* location)
1028 jack_nframes_t when_to_stop = location->end();
1030 replace_event (Event::PunchIn, location->start());
1031 //when_to_stop += _worst_output_latency + _worst_input_latency;
1032 replace_event (Event::PunchOut, when_to_stop);
1036 Session::auto_loop_changed (Location* location)
1038 replace_event (Event::AutoLoop, location->end(), location->start());
1040 if (transport_rolling() && get_auto_loop()) {
1042 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1044 if (_transport_frame > location->end()) {
1045 // relocate to beginning of loop
1046 clear_events (Event::LocateRoll);
1048 request_locate (location->start(), true);
1051 else if (seamless_loop && !loop_changing) {
1053 // schedule a locate-roll to refill the diskstreams at the
1054 // previous loop end
1055 loop_changing = true;
1057 if (location->end() > last_loopend) {
1058 clear_events (Event::LocateRoll);
1059 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1066 last_loopend = location->end();
1071 Session::set_auto_punch_location (Location* location)
1075 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1076 auto_punch_start_changed_connection.disconnect();
1077 auto_punch_end_changed_connection.disconnect();
1078 auto_punch_changed_connection.disconnect();
1079 existing->set_auto_punch (false, this);
1080 remove_event (existing->start(), Event::PunchIn);
1081 clear_events (Event::PunchOut);
1082 auto_punch_location_changed (0);
1087 if (location == 0) {
1091 if (location->end() <= location->start()) {
1092 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1096 auto_punch_start_changed_connection.disconnect();
1097 auto_punch_end_changed_connection.disconnect();
1098 auto_punch_changed_connection.disconnect();
1100 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1101 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1102 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1104 location->set_auto_punch (true, this);
1105 auto_punch_location_changed (location);
1109 Session::set_punch_in (bool yn)
1111 if (punch_in == yn) {
1117 if ((location = _locations.auto_punch_location()) != 0) {
1118 if ((punch_in = yn) == true) {
1119 replace_event (Event::PunchIn, location->start());
1121 remove_event (location->start(), Event::PunchIn);
1126 ControlChanged (PunchIn); /* EMIT SIGNAL */
1130 Session::set_punch_out (bool yn)
1132 if (punch_out == yn) {
1138 if ((location = _locations.auto_punch_location()) != 0) {
1139 if ((punch_out = yn) == true) {
1140 replace_event (Event::PunchOut, location->end());
1142 clear_events (Event::PunchOut);
1147 ControlChanged (PunchOut); /* EMIT SIGNAL */
1151 Session::set_auto_loop_location (Location* location)
1155 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1156 auto_loop_start_changed_connection.disconnect();
1157 auto_loop_end_changed_connection.disconnect();
1158 auto_loop_changed_connection.disconnect();
1159 existing->set_auto_loop (false, this);
1160 remove_event (existing->end(), Event::AutoLoop);
1161 auto_loop_location_changed (0);
1166 if (location == 0) {
1170 if (location->end() <= location->start()) {
1171 error << _("Session: you can't use a mark for auto loop") << endmsg;
1175 last_loopend = location->end();
1177 auto_loop_start_changed_connection.disconnect();
1178 auto_loop_end_changed_connection.disconnect();
1179 auto_loop_changed_connection.disconnect();
1181 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1182 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1183 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1185 location->set_auto_loop (true, this);
1186 auto_loop_location_changed (location);
1190 Session::locations_added (Location* ignored)
1196 Session::locations_changed ()
1198 _locations.apply (*this, &Session::handle_locations_changed);
1202 Session::handle_locations_changed (Locations::LocationList& locations)
1204 Locations::LocationList::iterator i;
1206 bool set_loop = false;
1207 bool set_punch = false;
1209 for (i = locations.begin(); i != locations.end(); ++i) {
1213 if (location->is_auto_punch()) {
1214 set_auto_punch_location (location);
1217 if (location->is_auto_loop()) {
1218 set_auto_loop_location (location);
1225 set_auto_loop_location (0);
1228 set_auto_punch_location (0);
1235 Session::enable_record ()
1237 /* XXX really atomic compare+swap here */
1238 if (atomic_read (&_record_status) != Recording) {
1239 atomic_set (&_record_status, Recording);
1240 _last_record_location = _transport_frame;
1241 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1243 if (Config->get_use_hardware_monitoring() && auto_input) {
1244 /* Even though this can be called from RT context we are using
1245 a non-tentative rwlock here, because the action must occur.
1246 The rarity and short potential lock duration makes this "OK"
1248 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1250 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1251 if ((*i)->record_enabled ()) {
1252 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
1253 (*i)->monitor_input (true);
1263 Session::disable_record ()
1265 if (atomic_read (&_record_status) != Disabled) {
1266 atomic_set (&_record_status, Disabled);
1267 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1269 if (Config->get_use_hardware_monitoring() && auto_input) {
1270 /* Even though this can be called from RT context we are using
1271 a non-tentative rwlock here, because the action must occur.
1272 The rarity and short potential lock duration makes this "OK"
1274 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1276 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1277 if ((*i)->record_enabled ()) {
1278 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1279 (*i)->monitor_input (false);
1285 remove_pending_capture_state ();
1291 Session::step_back_from_record ()
1293 atomic_set (&_record_status, Enabled);
1295 if (Config->get_use_hardware_monitoring()) {
1296 /* Even though this can be called from RT context we are using
1297 a non-tentative rwlock here, because the action must occur.
1298 The rarity and short potential lock duration makes this "OK"
1300 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1302 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1303 if (auto_input && (*i)->record_enabled ()) {
1304 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1305 (*i)->monitor_input (false);
1312 Session::maybe_enable_record ()
1314 atomic_set (&_record_status, Enabled);
1316 save_state ("", true);
1318 if (_transport_speed) {
1323 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1324 RecordEnabled (); /* EMIT SIGNAL */
1331 Session::audible_frame () const
1334 jack_nframes_t offset;
1337 /* the first of these two possible settings for "offset"
1338 mean that the audible frame is stationary until
1339 audio emerges from the latency compensation
1342 the second means that the audible frame is stationary
1343 until audio would emerge from a physical port
1344 in the absence of any plugin latency compensation
1347 offset = _worst_output_latency;
1349 if (offset > current_block_size) {
1350 offset -= current_block_size;
1352 /* XXX is this correct? if we have no external
1353 physical connections and everything is internal
1354 then surely this is zero? still, how
1355 likely is that anyway?
1357 offset = current_block_size;
1360 if (synced_to_jack()) {
1361 tf = _engine.transport_frame();
1363 tf = _transport_frame;
1366 if (_transport_speed == 0) {
1376 if (!non_realtime_work_pending()) {
1380 /* take latency into account */
1389 Session::set_frame_rate (jack_nframes_t frames_per_second)
1391 /** \fn void Session::set_frame_size(jack_nframes_t)
1392 the AudioEngine object that calls this guarantees
1393 that it will not be called while we are also in
1394 ::process(). Its fine to do things that block
1398 _current_frame_rate = frames_per_second;
1399 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1401 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1405 /* XXX need to reset/reinstantiate all LADSPA plugins */
1409 Session::set_block_size (jack_nframes_t nframes)
1411 /* the AudioEngine guarantees
1412 that it will not be called while we are also in
1413 ::process(). It is therefore fine to do things that block
1418 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1419 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1420 vector<Sample*>::iterator i;
1423 current_block_size = nframes;
1425 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1429 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1433 _passthru_buffers.clear ();
1434 _silent_buffers.clear ();
1436 ensure_passthru_buffers (np);
1438 if (_gain_automation_buffer) {
1439 delete [] _gain_automation_buffer;
1441 _gain_automation_buffer = new gain_t[nframes];
1443 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1445 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1446 (*i)->set_block_size (nframes);
1449 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1450 (*i)->set_block_size (nframes);
1453 set_worst_io_latencies (false);
1458 Session::set_default_fade (float steepness, float fade_msecs)
1461 jack_nframes_t fade_frames;
1463 /* Don't allow fade of less 1 frame */
1465 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1472 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1476 default_fade_msecs = fade_msecs;
1477 default_fade_steepness = steepness;
1480 // jlc, WTF is this!
1481 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1482 AudioRegion::set_default_fade (steepness, fade_frames);
1487 /* XXX have to do this at some point */
1488 /* foreach region using default fade, reset, then
1489 refill_all_diskstream_buffers ();
1494 struct RouteSorter {
1495 bool operator() (Route* r1, Route* r2) {
1496 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1498 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1501 if (r1->fed_by.empty()) {
1502 if (r2->fed_by.empty()) {
1503 /* no ardour-based connections inbound to either route. just use signal order */
1504 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1506 /* r2 has connections, r1 does not; run r1 early */
1510 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1517 trace_terminal (Route* r1, Route* rbase)
1521 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1522 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1526 /* make a copy of the existing list of routes that feed r1 */
1528 set<Route *> existing = r1->fed_by;
1530 /* for each route that feeds r1, recurse, marking it as feeding
1534 for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
1537 /* r2 is a route that feeds r1 which somehow feeds base. mark
1538 base as being fed by r2
1541 rbase->fed_by.insert (r2);
1545 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1549 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1553 /* now recurse, so that we can mark base as being fed by
1554 all routes that feed r2
1557 trace_terminal (r2, rbase);
1564 Session::resort_routes (void* src)
1566 /* don't do anything here with signals emitted
1567 by Routes while we are being destroyed.
1570 if (_state_of_the_state & Deletion) {
1574 /* Caller MUST hold the route_lock */
1576 RouteList::iterator i, j;
1578 for (i = routes.begin(); i != routes.end(); ++i) {
1580 (*i)->fed_by.clear ();
1582 for (j = routes.begin(); j != routes.end(); ++j) {
1584 /* although routes can feed themselves, it will
1585 cause an endless recursive descent if we
1586 detect it. so don't bother checking for
1594 if ((*j)->feeds (*i)) {
1595 (*i)->fed_by.insert (*j);
1600 for (i = routes.begin(); i != routes.end(); ++i) {
1601 trace_terminal (*i, *i);
1608 cerr << "finished route resort\n";
1610 for (i = routes.begin(); i != routes.end(); ++i) {
1611 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1619 Session::new_audio_track (int input_channels, int output_channels)
1622 char track_name[32];
1624 uint32_t channels_used = 0;
1626 uint32_t nphysical_in;
1627 uint32_t nphysical_out;
1629 /* count existing audio tracks */
1632 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1633 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1634 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1635 if (!(*i)->hidden()) {
1637 channels_used += (*i)->n_inputs();
1643 /* check for duplicate route names, since we might have pre-existing
1644 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1645 save, close,restart,add new route - first named route is now
1650 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1651 if (route_by_name (track_name) == 0) {
1656 } while (n < (UINT_MAX-1));
1658 if (input_auto_connect & AutoConnectPhysical) {
1659 nphysical_in = n_physical_inputs;
1664 if (output_auto_connect & AutoConnectPhysical) {
1665 nphysical_out = n_physical_outputs;
1671 track = new AudioTrack (*this, track_name);
1673 if (track->ensure_io (input_channels, output_channels, false, this)) {
1674 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1675 input_channels, output_channels)
1680 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1684 if (input_auto_connect & AutoConnectPhysical) {
1685 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1688 if (port.length() && track->connect_input (track->input (x), port, this)) {
1694 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1698 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1699 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1700 } else if (output_auto_connect & AutoConnectMaster) {
1702 port = _master_out->input (x%_master_out->n_inputs())->name();
1706 if (port.length() && track->connect_output (track->output (x), port, this)) {
1712 vector<string> cports;
1713 uint32_t ni = _control_out->n_inputs();
1715 for (n = 0; n < ni; ++n) {
1716 cports.push_back (_control_out->input(n)->name());
1719 track->set_control_outs (cports);
1722 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1726 track->set_remote_control_id (ntracks());
1729 catch (failed_constructor &err) {
1730 error << _("Session: could not create new audio track.") << endmsg;
1738 Session::new_audio_route (int input_channels, int output_channels)
1745 /* count existing audio busses */
1748 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1749 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1750 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1751 if (!(*i)->hidden()) {
1759 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1760 if (route_by_name (bus_name) == 0) {
1765 } while (n < (UINT_MAX-1));
1768 bus = new Route (*this, bus_name, -1, -1, -1, -1);
1770 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1771 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1772 input_channels, output_channels)
1776 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1780 if (input_auto_connect & AutoConnectPhysical) {
1781 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1784 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1789 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1793 if (output_auto_connect & AutoConnectPhysical) {
1794 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1795 } else if (output_auto_connect & AutoConnectMaster) {
1797 port = _master_out->input (x%_master_out->n_inputs())->name();
1801 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1807 vector<string> cports;
1808 uint32_t ni = _control_out->n_inputs();
1810 for (uint32_t n = 0; n < ni; ++n) {
1811 cports.push_back (_control_out->input(n)->name());
1813 bus->set_control_outs (cports);
1819 catch (failed_constructor &err) {
1820 error << _("Session: could not create new route.") << endmsg;
1828 Session::add_route (Route* route)
1831 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1832 routes.push_front (route);
1836 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1837 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1838 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1839 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1841 if (route->master()) {
1842 _master_out = route;
1845 if (route->control()) {
1846 _control_out = route;
1850 save_state (_current_snapshot_name);
1852 RouteAdded (route); /* EMIT SIGNAL */
1856 Session::add_diskstream (DiskStream* dstream)
1858 /* need to do this in case we're rolling at the time, to prevent false underruns */
1859 dstream->do_refill(0, 0);
1862 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1863 diskstreams.push_back (dstream);
1866 /* take a reference to the diskstream, preventing it from
1867 ever being deleted until the session itself goes away,
1868 or chooses to remove it for its own purposes.
1872 dstream->set_block_size (current_block_size);
1874 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1875 /* this will connect to future changes, and check the current length */
1876 diskstream_playlist_changed (dstream);
1878 dstream->prepare ();
1881 save_state (_current_snapshot_name);
1883 DiskStreamAdded (dstream); /* EMIT SIGNAL */
1887 Session::remove_route (Route& route)
1890 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1891 routes.remove (&route);
1893 /* deleting the master out seems like a dumb
1894 idea, but its more of a UI policy issue
1898 if (&route == _master_out) {
1902 if (&route == _control_out) {
1905 /* cancel control outs for all routes */
1907 vector<string> empty;
1909 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
1910 (*r)->set_control_outs (empty);
1914 update_route_solo_state ();
1918 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1922 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
1923 diskstreams.remove (&at->disk_stream());
1924 at->disk_stream().unref ();
1927 find_current_end ();
1930 update_latency_compensation (false, false);
1933 /* XXX should we disconnect from the Route's signals ? */
1935 save_state (_current_snapshot_name);
1941 Session::route_mute_changed (void* src)
1947 Session::route_solo_changed (void* src, Route* route)
1949 if (solo_update_disabled) {
1954 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1957 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
1959 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1961 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1965 /* don't mess with busses */
1967 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1973 /* don't mess with tracks */
1975 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1980 if ((*i) != route &&
1981 ((*i)->mix_group () == 0 ||
1982 (*i)->mix_group () != route->mix_group () ||
1983 !route->mix_group ()->is_active())) {
1985 if ((*i)->soloed()) {
1987 /* if its already soloed, and solo latching is enabled,
1988 then leave it as it is.
1991 if (_solo_latched) {
1998 solo_update_disabled = true;
1999 (*i)->set_solo (false, src);
2000 solo_update_disabled = false;
2004 bool something_soloed = false;
2005 bool same_thing_soloed = false;
2006 bool signal = false;
2008 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2009 if ((*i)->soloed()) {
2010 something_soloed = true;
2011 if (dynamic_cast<AudioTrack*>(*i)) {
2013 same_thing_soloed = true;
2018 same_thing_soloed = true;
2026 if (something_soloed != currently_soloing) {
2028 currently_soloing = something_soloed;
2031 modify_solo_mute (is_track, same_thing_soloed);
2034 SoloActive (currently_soloing);
2041 Session::set_solo_latched (bool yn)
2043 if (yn != _solo_latched) {
2046 ControlChanged (SoloLatch);
2051 Session::update_route_solo_state ()
2054 bool is_track = false;
2055 bool signal = false;
2057 /* caller must hold RouteLock */
2059 /* this is where we actually implement solo by changing
2060 the solo mute setting of each track.
2063 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2064 if ((*i)->soloed()) {
2066 if (dynamic_cast<AudioTrack*>(*i)) {
2073 if (mute != currently_soloing) {
2075 currently_soloing = mute;
2078 if (!is_track && !mute) {
2080 /* nothing is soloed */
2082 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2083 (*i)->set_solo_mute (false);
2093 modify_solo_mute (is_track, mute);
2096 SoloActive (currently_soloing);
2101 Session::modify_solo_mute (bool is_track, bool mute)
2103 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2107 /* only alter track solo mute */
2109 if (dynamic_cast<AudioTrack*>(*i)) {
2110 if ((*i)->soloed()) {
2111 (*i)->set_solo_mute (!mute);
2113 (*i)->set_solo_mute (mute);
2119 /* only alter bus solo mute */
2121 if (!dynamic_cast<AudioTrack*>(*i)) {
2123 if ((*i)->soloed()) {
2125 (*i)->set_solo_mute (false);
2129 /* don't mute master or control outs
2130 in response to another bus solo
2133 if ((*i) != _master_out &&
2134 (*i) != _control_out) {
2135 (*i)->set_solo_mute (mute);
2146 Session::catch_up_on_solo ()
2148 /* this is called after set_state() to catch the full solo
2149 state, which can't be correctly determined on a per-route
2150 basis, but needs the global overview that only the session
2153 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2154 update_route_solo_state();
2158 Session::route_by_name (string name)
2160 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2162 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2163 if ((*i)->name() == name) {
2172 Session::find_current_end ()
2174 jack_nframes_t max = 0;
2177 if (_state_of_the_state & Loading) {
2181 /* Don't take the diskstream lock. Caller must have other ways to
2185 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2186 Playlist* pl = (*i)->playlist();
2187 if ((me = pl->get_maximum_extent()) > max) {
2192 if (max > end_location->end()) {
2193 end_location->set_end (max);
2195 DurationChanged(); /* EMIT SIGNAL */
2200 Session::diskstream_by_name (string name)
2202 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2204 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2205 if ((*i)->name() == name) {
2214 Session::diskstream_by_id (id_t id)
2216 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2218 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2219 if ((*i)->id() == id) {
2227 /* AudioRegion management */
2230 Session::new_region_name (string old)
2232 string::size_type last_period;
2234 string::size_type len = old.length() + 64;
2237 if ((last_period = old.find_last_of ('.')) == string::npos) {
2239 /* no period present - add one explicitly */
2242 last_period = old.length() - 1;
2247 number = atoi (old.substr (last_period+1).c_str());
2251 while (number < (UINT_MAX-1)) {
2253 AudioRegionList::const_iterator i;
2258 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2261 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2262 if ((*i).second->name() == sbuf) {
2267 if (i == audio_regions.end()) {
2272 if (number != (UINT_MAX-1)) {
2276 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2281 Session::region_name (string& result, string base, bool newlevel) const
2288 LockMonitor lm (region_lock, __LINE__, __FILE__);
2290 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2298 /* XXX this is going to be slow. optimize me later */
2303 string::size_type pos;
2305 if ((pos = base.find_last_of ('-')) == string::npos) {
2306 pos = base.find_last_of ('.');
2309 /* pos may be npos, but then we just use entire base */
2311 subbase = base.substr (0, pos);
2314 bool name_taken = true;
2317 LockMonitor lm (region_lock, __LINE__, __FILE__);
2319 for (int n = 1; n < 5000; ++n) {
2322 snprintf (buf, sizeof (buf), ".%d", n);
2327 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2328 if ((*i).second->name() == result) {
2341 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2350 Session::add_region (Region* region)
2352 AudioRegion* ar = 0;
2353 AudioRegion* oar = 0;
2357 LockMonitor lm (region_lock, __LINE__, __FILE__);
2359 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2361 AudioRegionList::iterator x;
2363 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2365 oar = dynamic_cast<AudioRegion*> (x->second);
2367 if (ar->region_list_equivalent (*oar)) {
2372 if (x == audio_regions.end()) {
2374 pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry;
2376 entry.first = region->id();
2379 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2390 fatal << _("programming error: ")
2391 << X_("unknown region type passed to Session::add_region()")
2398 /* mark dirty because something has changed even if we didn't
2399 add the region to the region list.
2405 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2406 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2407 AudioRegionAdded (ar); /* EMIT SIGNAL */
2412 Session::region_changed (Change what_changed, Region* region)
2414 if (what_changed & Region::HiddenChanged) {
2415 /* relay hidden changes */
2416 RegionHiddenChange (region);
2421 Session::region_renamed (Region* region)
2423 add_region (region);
2427 Session::remove_region (Region* region)
2429 AudioRegionList::iterator i;
2430 AudioRegion* ar = 0;
2431 bool removed = false;
2434 LockMonitor lm (region_lock, __LINE__, __FILE__);
2436 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2437 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2438 audio_regions.erase (i);
2442 fatal << _("programming error: ")
2443 << X_("unknown region type passed to Session::remove_region()")
2449 /* mark dirty because something has changed even if we didn't
2450 remove the region from the region list.
2456 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2461 Session::find_whole_file_parent (AudioRegion& child)
2463 AudioRegionList::iterator i;
2464 AudioRegion* region;
2465 LockMonitor lm (region_lock, __LINE__, __FILE__);
2467 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2469 region = (*i).second;
2471 if (region->whole_file()) {
2473 if (child.source_equivalent (*region)) {
2483 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2485 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2489 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2493 pl->get_region_list_equivalent_regions (region, result);
2498 Session::destroy_region (Region* region)
2500 AudioRegion* aregion;
2502 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2506 if (aregion->playlist()) {
2507 aregion->playlist()->destroy_region (region);
2510 vector<Source*> srcs;
2512 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2513 srcs.push_back (&aregion->source (n));
2516 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2518 if ((*i)->use_cnt() == 0) {
2519 (*i)->mark_for_remove ();
2528 Session::destroy_regions (list<Region*> regions)
2530 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2531 destroy_region (*i);
2537 Session::remove_last_capture ()
2541 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2543 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2544 list<Region*>& l = (*i)->last_capture_regions();
2547 r.insert (r.end(), l.begin(), l.end());
2552 destroy_regions (r);
2557 Session::remove_region_from_region_list (Region& r)
2563 /* Source Management */
2566 Session::add_source (Source* source)
2568 pair<SourceList::key_type, SourceList::mapped_type> entry;
2571 LockMonitor lm (source_lock, __LINE__, __FILE__);
2572 entry.first = source->id();
2573 entry.second = source;
2574 sources.insert (entry);
2577 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2580 SourceAdded (source); /* EMIT SIGNAL */
2584 Session::remove_source (Source* source)
2586 SourceList::iterator i;
2589 LockMonitor lm (source_lock, __LINE__, __FILE__);
2591 if ((i = sources.find (source->id())) != sources.end()) {
2596 if (!_state_of_the_state & InCleanup) {
2598 /* save state so we don't end up with a session file
2599 referring to non-existent sources.
2602 save_state (_current_snapshot_name);
2605 SourceRemoved(source); /* EMIT SIGNAL */
2609 Session::get_source (ARDOUR::id_t id)
2611 LockMonitor lm (source_lock, __LINE__, __FILE__);
2612 SourceList::iterator i;
2615 if ((i = sources.find (id)) != sources.end()) {
2616 source = (*i).second;
2623 Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
2627 char buf[PATH_MAX+1];
2628 const uint32_t limit = 10000;
2632 legalized = legalize_for_path (ds.name());
2634 /* find a "version" of the file name that doesn't exist in
2635 any of the possible directories.
2638 for (cnt = 1; cnt <= limit; ++cnt) {
2640 vector<space_and_path>::iterator i;
2641 uint32_t existing = 0;
2643 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2646 spath += sound_dir_name;
2650 if (ds.n_channels() < 2) {
2651 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2652 } else if (ds.n_channels() == 2) {
2654 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2656 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2658 } else if (ds.n_channels() < 26) {
2659 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2661 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2664 if (access (buf, F_OK) == 0) {
2669 if (existing == 0) {
2675 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, ds.name()) << endmsg;
2676 throw failed_constructor();
2679 /* we now have a unique name for the file, but figure out where to
2685 spath = discover_best_sound_dir ();
2687 string::size_type pos = foo.find_last_of ('/');
2689 if (pos == string::npos) {
2692 spath += foo.substr (pos + 1);
2695 /* this might throw failed_constructor(), which is OK */
2698 return new DestructiveFileSource (spath, frame_rate());
2700 return new FileSource (spath, frame_rate());
2704 /* Playlist management */
2707 Session::get_playlist (string name)
2711 if ((ret = playlist_by_name (name)) == 0) {
2712 ret = new AudioPlaylist (*this, name);
2719 Session::playlist_by_name (string name)
2721 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2722 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2723 if ((*i)->name() == name) {
2727 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2728 if ((*i)->name() == name) {
2736 Session::add_playlist (Playlist* playlist)
2738 if (playlist->hidden()) {
2743 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2744 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2745 playlists.insert (playlists.begin(), playlist);
2747 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2748 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2754 PlaylistAdded (playlist); /* EMIT SIGNAL */
2758 Session::track_playlist (Playlist* pl, bool inuse)
2760 PlaylistList::iterator x;
2763 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2766 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2768 unused_playlists.insert (pl);
2770 if ((x = playlists.find (pl)) != playlists.end()) {
2771 playlists.erase (x);
2776 //cerr << "shifting playlist to used: " << pl->name() << endl;
2778 playlists.insert (pl);
2780 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2781 unused_playlists.erase (x);
2788 Session::remove_playlist (Playlist* playlist)
2790 if (_state_of_the_state & Deletion) {
2795 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2796 // cerr << "removing playlist: " << playlist->name() << endl;
2798 PlaylistList::iterator i;
2800 i = find (playlists.begin(), playlists.end(), playlist);
2802 if (i != playlists.end()) {
2803 playlists.erase (i);
2806 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
2807 if (i != unused_playlists.end()) {
2808 unused_playlists.erase (i);
2815 PlaylistRemoved (playlist); /* EMIT SIGNAL */
2819 Session::set_audition (AudioRegion* r)
2821 pending_audition_region = r;
2822 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
2823 schedule_butler_transport_work ();
2827 Session::non_realtime_set_audition ()
2829 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
2830 auditioner->audition_current_playlist ();
2831 } else if (pending_audition_region) {
2832 auditioner->audition_region (*pending_audition_region);
2834 pending_audition_region = 0;
2835 AuditionActive (true); /* EMIT SIGNAL */
2839 Session::audition_playlist ()
2841 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
2842 ev->set_ptr ((void*) 0xfeedface);
2847 Session::audition_region (AudioRegion& r)
2849 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
2855 Session::cancel_audition ()
2857 if (auditioner->active()) {
2858 auditioner->cancel_audition ();
2859 AuditionActive (false); /* EMIT SIGNAL */
2864 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
2866 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
2870 Session::remove_empty_sounds ()
2873 PathScanner scanner;
2878 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
2880 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
2882 if (FileSource::is_empty (*(*i))) {
2884 unlink ((*i)->c_str());
2886 string peak_path = peak_path_from_audio_path (**i);
2887 unlink (peak_path.c_str());
2893 delete possible_audiofiles;
2897 Session::is_auditioning () const
2899 /* can be called before we have an auditioner object */
2901 return auditioner->active();
2909 Session::peak_path_from_audio_path (string audio_path)
2911 /* XXX hardly bombproof! fix me */
2915 res = PBD::dirname (audio_path);
2916 res = PBD::dirname (res);
2918 res += peak_dir_name;
2920 res += PBD::basename_nosuffix (audio_path);
2927 Session::old_peak_path_from_audio_path (string audio_path)
2929 /* This is a hangover from when audio and peak files
2930 lived in the same directory. We need it to to
2931 be able to open old sessions.
2934 /* XXX hardly bombproof! fix me */
2936 string res = audio_path.substr (0, audio_path.find_last_of ('.'));
2942 Session::set_all_solo (bool yn)
2945 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2947 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2948 if (!(*i)->hidden()) {
2949 (*i)->set_solo (yn, this);
2958 Session::set_all_mute (bool yn)
2961 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2963 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2964 if (!(*i)->hidden()) {
2965 (*i)->set_mute (yn, this);
2974 Session::n_diskstreams () const
2976 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2979 for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2980 if (!(*i)->hidden()) {
2988 Session::foreach_diskstream (void (DiskStream::*func)(void))
2990 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2991 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2992 if (!(*i)->hidden()) {
2999 Session::graph_reordered ()
3001 /* don't do this stuff if we are setting up connections
3002 from a set_state() call.
3005 if (_state_of_the_state & InitialConnecting) {
3009 RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3010 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3014 /* force all diskstreams to update their capture offset values to
3015 reflect any changes in latencies within the graph.
3018 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3019 (*i)->set_capture_offset ();
3024 Session::record_disenable_all ()
3026 record_enable_change_all (false);
3030 Session::record_enable_all ()
3032 record_enable_change_all (true);
3036 Session::record_enable_change_all (bool yn)
3038 RWLockMonitor lm1 (route_lock, false, __LINE__, __FILE__);
3040 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3043 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3044 at->set_record_enable (yn, this);
3048 /* since we don't keep rec-enable state, don't mark session dirty */
3052 Session::add_redirect (Redirect* redirect)
3056 PortInsert* port_insert;
3057 PluginInsert* plugin_insert;
3059 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3060 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3061 _port_inserts.insert (_port_inserts.begin(), port_insert);
3062 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3063 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3065 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3068 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3069 _sends.insert (_sends.begin(), send);
3071 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3075 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3081 Session::remove_redirect (Redirect* redirect)
3085 PortInsert* port_insert;
3086 PluginInsert* plugin_insert;
3088 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3089 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3090 _port_inserts.remove (port_insert);
3091 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3092 _plugin_inserts.remove (plugin_insert);
3094 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3097 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3098 _sends.remove (send);
3100 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3108 Session::available_capture_duration ()
3110 const double scale = 4096.0 / sizeof (Sample);
3112 if (_total_free_4k_blocks * scale > (double) max_frames) {
3116 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3120 Session::add_connection (ARDOUR::Connection* connection)
3123 LockMonitor (connection_lock, __LINE__, __FILE__);
3124 _connections.push_back (connection);
3127 ConnectionAdded (connection); /* EMIT SIGNAL */
3133 Session::remove_connection (ARDOUR::Connection* connection)
3135 bool removed = false;
3138 LockMonitor (connection_lock, __LINE__, __FILE__);
3139 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3141 if (i != _connections.end()) {
3142 _connections.erase (i);
3148 ConnectionRemoved (connection); /* EMIT SIGNAL */
3154 ARDOUR::Connection *
3155 Session::connection_by_name (string name) const
3157 LockMonitor lm (connection_lock, __LINE__, __FILE__);
3159 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3160 if ((*i)->name() == name) {
3169 Session::set_edit_mode (EditMode mode)
3174 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3176 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3177 (*i)->set_edit_mode (mode);
3182 ControlChanged (EditingMode); /* EMIT SIGNAL */
3186 Session::tempo_map_changed (Change ignored)
3193 Session::ensure_passthru_buffers (uint32_t howmany)
3195 while (howmany > _passthru_buffers.size()) {
3197 #ifdef NO_POSIX_MEMALIGN
3198 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3200 posix_memalign((void **)&p,16,current_block_size * 4);
3202 _passthru_buffers.push_back (p);
3206 #ifdef NO_POSIX_MEMALIGN
3207 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3209 posix_memalign((void **)&p,16,current_block_size * 4);
3211 memset (p, 0, sizeof (Sample) * current_block_size);
3212 _silent_buffers.push_back (p);
3215 allocate_pan_automation_buffers (current_block_size, howmany, false);
3219 Session::next_send_name ()
3222 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3227 Session::next_insert_name ()
3230 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3234 /* Named Selection management */
3237 Session::named_selection_by_name (string name)
3239 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3240 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3241 if ((*i)->name == name) {
3249 Session::add_named_selection (NamedSelection* named_selection)
3252 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3253 named_selections.insert (named_selections.begin(), named_selection);
3258 NamedSelectionAdded (); /* EMIT SIGNAL */
3262 Session::remove_named_selection (NamedSelection* named_selection)
3264 bool removed = false;
3267 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3269 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3271 if (i != named_selections.end()) {
3273 named_selections.erase (i);
3280 NamedSelectionRemoved (); /* EMIT SIGNAL */
3285 Session::reset_native_file_format ()
3287 // jlc - WHY take routelock?
3288 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3289 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3291 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3292 (*i)->reset_write_sources (false);
3297 Session::route_name_unique (string n) const
3299 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3301 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3302 if ((*i)->name() == n) {
3311 Session::remove_file_source (FileSource& fs)
3313 return fs.move_to_trash (dead_sound_dir_name);
3317 Session::n_playlists () const
3319 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3320 return playlists.size();
3324 Session::set_solo_model (SoloModel sm)
3326 if (sm != _solo_model) {
3328 ControlChanged (SoloingModel);
3334 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3336 if (!force && howmany <= _npan_buffers) {
3340 if (_pan_automation_buffer) {
3342 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3343 delete [] _pan_automation_buffer[i];
3346 delete [] _pan_automation_buffer;
3349 _pan_automation_buffer = new pan_t*[howmany];
3351 for (uint32_t i = 0; i < howmany; ++i) {
3352 _pan_automation_buffer[i] = new pan_t[nframes];
3355 _npan_buffers = howmany;
3359 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3361 Stateful::add_instant_xml (node, dir);
3362 Config->add_instant_xml (node, Config->get_user_ardour_path());
3366 Session::freeze (InterThreadInfo& itt)
3368 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3370 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3374 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3375 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3386 Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len, bool overwrite, vector<Source*>& srcs,
3387 InterThreadInfo& itt)
3391 FileSource* fsource;
3393 char buf[PATH_MAX+1];
3396 jack_nframes_t position;
3397 jack_nframes_t this_chunk;
3398 jack_nframes_t to_do;
3399 vector<Sample*> buffers;
3400 const jack_nframes_t chunk_size = (256 * 1024)/4;
3402 atomic_set (&processing_prohibited, 1);
3404 /* call tree *MUST* hold route_lock */
3406 if ((playlist = track.disk_stream().playlist()) == 0) {
3410 /* external redirects will be a problem */
3412 if (track.has_external_redirects()) {
3416 nchans = track.disk_stream().n_channels();
3418 dir = discover_best_sound_dir ();
3420 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3422 for (x = 0; x < 99999; ++x) {
3423 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3424 if (access (buf, F_OK) != 0) {
3430 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3435 fsource = new FileSource (buf, frame_rate());
3438 catch (failed_constructor& err) {
3439 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3443 srcs.push_back(fsource);
3446 /* XXX need to flush all redirects */
3451 /* create a set of reasonably-sized buffers */
3453 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3455 #ifdef NO_POSIX_MEMALIGN
3456 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3458 posix_memalign((void **)&b,16,chunk_size * 4);
3460 buffers.push_back (b);
3463 while (to_do && !itt.cancel) {
3465 this_chunk = min (to_do, chunk_size);
3467 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3472 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3473 if ((*src)->write (buffers[n], this_chunk) != this_chunk) {
3478 start += this_chunk;
3479 to_do -= this_chunk;
3481 itt.progress = (float) (1.0 - ((double) to_do / len));
3490 xnow = localtime (&now);
3492 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3493 dynamic_cast<FileSource*>((*src))->update_header (position, *xnow, now);
3496 /* build peakfile for new source */
3498 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3499 dynamic_cast<FileSource*>(*src)->build_peaks ();
3507 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3508 dynamic_cast<FileSource*>(*src)->mark_for_remove ();
3513 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3517 atomic_set (&processing_prohibited, 0);
3525 Session::get_silent_buffers (uint32_t howmany)
3527 for (uint32_t i = 0; i < howmany; ++i) {
3528 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3530 return _silent_buffers;
3534 Session::ntracks () const
3537 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3539 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3540 if (dynamic_cast<AudioTrack*> (*i)) {
3549 Session::nbusses () const
3552 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3554 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3555 if (dynamic_cast<AudioTrack*> (*i) == 0) {
3564 Session::set_layer_model (LayerModel lm)
3566 if (lm != layer_model) {
3569 ControlChanged (LayeringModel);
3574 Session::set_xfade_model (CrossfadeModel xm)
3576 if (xm != xfade_model) {
3579 ControlChanged (CrossfadingModel);