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_do_not_record_plugins (bool yn)
925 if (do_not_record_plugins != yn) {
926 do_not_record_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 (*i)->monitor_input (true);
1257 RecordStateChanged ();
1262 Session::disable_record (bool force)
1266 if ((rs = (RecordState) atomic_read (&_record_status)) != Disabled) {
1268 if (!Config->get_latched_record_enable () || force) {
1269 atomic_set (&_record_status, Disabled);
1271 if (rs == Recording) {
1272 atomic_set (&_record_status, Enabled);
1276 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1278 if (Config->get_use_hardware_monitoring() && auto_input) {
1279 /* Even though this can be called from RT context we are using
1280 a non-tentative rwlock here, because the action must occur.
1281 The rarity and short potential lock duration makes this "OK"
1283 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1285 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1286 if ((*i)->record_enabled ()) {
1287 (*i)->monitor_input (false);
1292 RecordStateChanged (); /* emit signal */
1293 remove_pending_capture_state ();
1298 Session::step_back_from_record ()
1300 atomic_set (&_record_status, Enabled);
1302 if (Config->get_use_hardware_monitoring()) {
1303 /* Even though this can be called from RT context we are using
1304 a non-tentative rwlock here, because the action must occur.
1305 The rarity and short potential lock duration makes this "OK"
1307 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1309 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1310 if (auto_input && (*i)->record_enabled ()) {
1311 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1312 (*i)->monitor_input (false);
1319 Session::maybe_enable_record ()
1321 atomic_set (&_record_status, Enabled);
1323 save_state ("", true);
1325 if (_transport_speed) {
1330 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1331 RecordStateChanged (); /* EMIT SIGNAL */
1338 Session::audible_frame () const
1341 jack_nframes_t offset;
1344 /* the first of these two possible settings for "offset"
1345 mean that the audible frame is stationary until
1346 audio emerges from the latency compensation
1349 the second means that the audible frame is stationary
1350 until audio would emerge from a physical port
1351 in the absence of any plugin latency compensation
1354 offset = _worst_output_latency;
1356 if (offset > current_block_size) {
1357 offset -= current_block_size;
1359 /* XXX is this correct? if we have no external
1360 physical connections and everything is internal
1361 then surely this is zero? still, how
1362 likely is that anyway?
1364 offset = current_block_size;
1367 if (synced_to_jack()) {
1368 tf = _engine.transport_frame();
1370 tf = _transport_frame;
1373 if (_transport_speed == 0) {
1383 if (!non_realtime_work_pending()) {
1387 /* take latency into account */
1396 Session::set_frame_rate (jack_nframes_t frames_per_second)
1398 /** \fn void Session::set_frame_size(jack_nframes_t)
1399 the AudioEngine object that calls this guarantees
1400 that it will not be called while we are also in
1401 ::process(). Its fine to do things that block
1405 _current_frame_rate = frames_per_second;
1406 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1408 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1412 /* XXX need to reset/reinstantiate all LADSPA plugins */
1416 Session::set_block_size (jack_nframes_t nframes)
1418 /* the AudioEngine guarantees
1419 that it will not be called while we are also in
1420 ::process(). It is therefore fine to do things that block
1425 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1426 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1427 vector<Sample*>::iterator i;
1430 current_block_size = nframes;
1432 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1436 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1440 _passthru_buffers.clear ();
1441 _silent_buffers.clear ();
1443 ensure_passthru_buffers (np);
1445 if (_gain_automation_buffer) {
1446 delete [] _gain_automation_buffer;
1448 _gain_automation_buffer = new gain_t[nframes];
1450 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1452 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1453 (*i)->set_block_size (nframes);
1456 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1457 (*i)->set_block_size (nframes);
1460 set_worst_io_latencies (false);
1465 Session::set_default_fade (float steepness, float fade_msecs)
1468 jack_nframes_t fade_frames;
1470 /* Don't allow fade of less 1 frame */
1472 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1479 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1483 default_fade_msecs = fade_msecs;
1484 default_fade_steepness = steepness;
1487 // jlc, WTF is this!
1488 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1489 AudioRegion::set_default_fade (steepness, fade_frames);
1494 /* XXX have to do this at some point */
1495 /* foreach region using default fade, reset, then
1496 refill_all_diskstream_buffers ();
1501 struct RouteSorter {
1502 bool operator() (Route* r1, Route* r2) {
1503 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1505 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1508 if (r1->fed_by.empty()) {
1509 if (r2->fed_by.empty()) {
1510 /* no ardour-based connections inbound to either route. just use signal order */
1511 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1513 /* r2 has connections, r1 does not; run r1 early */
1517 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1524 trace_terminal (Route* r1, Route* rbase)
1528 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1529 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1533 /* make a copy of the existing list of routes that feed r1 */
1535 set<Route *> existing = r1->fed_by;
1537 /* for each route that feeds r1, recurse, marking it as feeding
1541 for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
1544 /* r2 is a route that feeds r1 which somehow feeds base. mark
1545 base as being fed by r2
1548 rbase->fed_by.insert (r2);
1552 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1556 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1560 /* now recurse, so that we can mark base as being fed by
1561 all routes that feed r2
1564 trace_terminal (r2, rbase);
1571 Session::resort_routes (void* src)
1573 /* don't do anything here with signals emitted
1574 by Routes while we are being destroyed.
1577 if (_state_of_the_state & Deletion) {
1581 /* Caller MUST hold the route_lock */
1583 RouteList::iterator i, j;
1585 for (i = routes.begin(); i != routes.end(); ++i) {
1587 (*i)->fed_by.clear ();
1589 for (j = routes.begin(); j != routes.end(); ++j) {
1591 /* although routes can feed themselves, it will
1592 cause an endless recursive descent if we
1593 detect it. so don't bother checking for
1601 if ((*j)->feeds (*i)) {
1602 (*i)->fed_by.insert (*j);
1607 for (i = routes.begin(); i != routes.end(); ++i) {
1608 trace_terminal (*i, *i);
1615 cerr << "finished route resort\n";
1617 for (i = routes.begin(); i != routes.end(); ++i) {
1618 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1626 Session::new_audio_track (int input_channels, int output_channels)
1629 char track_name[32];
1631 uint32_t channels_used = 0;
1633 uint32_t nphysical_in;
1634 uint32_t nphysical_out;
1636 /* count existing audio tracks */
1639 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1640 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1641 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1642 if (!(*i)->hidden()) {
1644 channels_used += (*i)->n_inputs();
1650 /* check for duplicate route names, since we might have pre-existing
1651 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1652 save, close,restart,add new route - first named route is now
1657 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1658 if (route_by_name (track_name) == 0) {
1663 } while (n < (UINT_MAX-1));
1665 if (input_auto_connect & AutoConnectPhysical) {
1666 nphysical_in = n_physical_inputs;
1671 if (output_auto_connect & AutoConnectPhysical) {
1672 nphysical_out = n_physical_outputs;
1678 track = new AudioTrack (*this, track_name);
1680 if (track->ensure_io (input_channels, output_channels, false, this)) {
1681 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1682 input_channels, output_channels)
1687 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1691 if (input_auto_connect & AutoConnectPhysical) {
1692 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1695 if (port.length() && track->connect_input (track->input (x), port, this)) {
1701 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1705 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1706 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1707 } else if (output_auto_connect & AutoConnectMaster) {
1709 port = _master_out->input (x%_master_out->n_inputs())->name();
1713 if (port.length() && track->connect_output (track->output (x), port, this)) {
1719 vector<string> cports;
1720 uint32_t ni = _control_out->n_inputs();
1722 for (n = 0; n < ni; ++n) {
1723 cports.push_back (_control_out->input(n)->name());
1726 track->set_control_outs (cports);
1729 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1733 track->set_remote_control_id (ntracks());
1736 catch (failed_constructor &err) {
1737 error << _("Session: could not create new audio track.") << endmsg;
1745 Session::new_audio_route (int input_channels, int output_channels)
1752 /* count existing audio busses */
1755 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1756 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1757 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1758 if (!(*i)->hidden()) {
1766 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1767 if (route_by_name (bus_name) == 0) {
1772 } while (n < (UINT_MAX-1));
1775 bus = new Route (*this, bus_name, -1, -1, -1, -1);
1777 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1778 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1779 input_channels, output_channels)
1783 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1787 if (input_auto_connect & AutoConnectPhysical) {
1788 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1791 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1796 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1800 if (output_auto_connect & AutoConnectPhysical) {
1801 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1802 } else if (output_auto_connect & AutoConnectMaster) {
1804 port = _master_out->input (x%_master_out->n_inputs())->name();
1808 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1814 vector<string> cports;
1815 uint32_t ni = _control_out->n_inputs();
1817 for (uint32_t n = 0; n < ni; ++n) {
1818 cports.push_back (_control_out->input(n)->name());
1820 bus->set_control_outs (cports);
1826 catch (failed_constructor &err) {
1827 error << _("Session: could not create new route.") << endmsg;
1835 Session::add_route (Route* route)
1838 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1839 routes.push_front (route);
1843 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1844 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1845 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1846 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1848 if (route->master()) {
1849 _master_out = route;
1852 if (route->control()) {
1853 _control_out = route;
1857 save_state (_current_snapshot_name);
1859 RouteAdded (route); /* EMIT SIGNAL */
1863 Session::add_diskstream (DiskStream* dstream)
1865 /* need to do this in case we're rolling at the time, to prevent false underruns */
1866 dstream->do_refill(0, 0);
1869 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1870 diskstreams.push_back (dstream);
1873 /* take a reference to the diskstream, preventing it from
1874 ever being deleted until the session itself goes away,
1875 or chooses to remove it for its own purposes.
1879 dstream->set_block_size (current_block_size);
1881 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1882 /* this will connect to future changes, and check the current length */
1883 diskstream_playlist_changed (dstream);
1885 dstream->prepare ();
1888 save_state (_current_snapshot_name);
1890 DiskStreamAdded (dstream); /* EMIT SIGNAL */
1894 Session::remove_route (Route& route)
1897 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1898 routes.remove (&route);
1900 /* deleting the master out seems like a dumb
1901 idea, but its more of a UI policy issue
1905 if (&route == _master_out) {
1909 if (&route == _control_out) {
1912 /* cancel control outs for all routes */
1914 vector<string> empty;
1916 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
1917 (*r)->set_control_outs (empty);
1921 update_route_solo_state ();
1925 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1929 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
1930 diskstreams.remove (&at->disk_stream());
1931 at->disk_stream().unref ();
1934 find_current_end ();
1937 update_latency_compensation (false, false);
1940 /* XXX should we disconnect from the Route's signals ? */
1942 save_state (_current_snapshot_name);
1948 Session::route_mute_changed (void* src)
1954 Session::route_solo_changed (void* src, Route* route)
1956 if (solo_update_disabled) {
1961 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1964 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
1966 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1968 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1972 /* don't mess with busses */
1974 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1980 /* don't mess with tracks */
1982 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1987 if ((*i) != route &&
1988 ((*i)->mix_group () == 0 ||
1989 (*i)->mix_group () != route->mix_group () ||
1990 !route->mix_group ()->is_active())) {
1992 if ((*i)->soloed()) {
1994 /* if its already soloed, and solo latching is enabled,
1995 then leave it as it is.
1998 if (_solo_latched) {
2005 solo_update_disabled = true;
2006 (*i)->set_solo (false, src);
2007 solo_update_disabled = false;
2011 bool something_soloed = false;
2012 bool same_thing_soloed = false;
2013 bool signal = false;
2015 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2016 if ((*i)->soloed()) {
2017 something_soloed = true;
2018 if (dynamic_cast<AudioTrack*>(*i)) {
2020 same_thing_soloed = true;
2025 same_thing_soloed = true;
2033 if (something_soloed != currently_soloing) {
2035 currently_soloing = something_soloed;
2038 modify_solo_mute (is_track, same_thing_soloed);
2041 SoloActive (currently_soloing);
2048 Session::set_solo_latched (bool yn)
2050 if (yn != _solo_latched) {
2053 ControlChanged (SoloLatch);
2058 Session::update_route_solo_state ()
2061 bool is_track = false;
2062 bool signal = false;
2064 /* caller must hold RouteLock */
2066 /* this is where we actually implement solo by changing
2067 the solo mute setting of each track.
2070 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2071 if ((*i)->soloed()) {
2073 if (dynamic_cast<AudioTrack*>(*i)) {
2080 if (mute != currently_soloing) {
2082 currently_soloing = mute;
2085 if (!is_track && !mute) {
2087 /* nothing is soloed */
2089 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2090 (*i)->set_solo_mute (false);
2100 modify_solo_mute (is_track, mute);
2103 SoloActive (currently_soloing);
2108 Session::modify_solo_mute (bool is_track, bool mute)
2110 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2114 /* only alter track solo mute */
2116 if (dynamic_cast<AudioTrack*>(*i)) {
2117 if ((*i)->soloed()) {
2118 (*i)->set_solo_mute (!mute);
2120 (*i)->set_solo_mute (mute);
2126 /* only alter bus solo mute */
2128 if (!dynamic_cast<AudioTrack*>(*i)) {
2130 if ((*i)->soloed()) {
2132 (*i)->set_solo_mute (false);
2136 /* don't mute master or control outs
2137 in response to another bus solo
2140 if ((*i) != _master_out &&
2141 (*i) != _control_out) {
2142 (*i)->set_solo_mute (mute);
2153 Session::catch_up_on_solo ()
2155 /* this is called after set_state() to catch the full solo
2156 state, which can't be correctly determined on a per-route
2157 basis, but needs the global overview that only the session
2160 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2161 update_route_solo_state();
2165 Session::route_by_name (string name)
2167 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2169 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2170 if ((*i)->name() == name) {
2179 Session::find_current_end ()
2181 jack_nframes_t max = 0;
2184 if (_state_of_the_state & Loading) {
2188 /* Don't take the diskstream lock. Caller must have other ways to
2192 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2193 Playlist* pl = (*i)->playlist();
2194 if ((me = pl->get_maximum_extent()) > max) {
2199 if (max > end_location->end()) {
2200 end_location->set_end (max);
2202 DurationChanged(); /* EMIT SIGNAL */
2207 Session::diskstream_by_name (string name)
2209 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2211 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2212 if ((*i)->name() == name) {
2221 Session::diskstream_by_id (id_t id)
2223 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2225 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2226 if ((*i)->id() == id) {
2234 /* AudioRegion management */
2237 Session::new_region_name (string old)
2239 string::size_type last_period;
2241 string::size_type len = old.length() + 64;
2244 if ((last_period = old.find_last_of ('.')) == string::npos) {
2246 /* no period present - add one explicitly */
2249 last_period = old.length() - 1;
2254 number = atoi (old.substr (last_period+1).c_str());
2258 while (number < (UINT_MAX-1)) {
2260 AudioRegionList::const_iterator i;
2265 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2268 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2269 if ((*i).second->name() == sbuf) {
2274 if (i == audio_regions.end()) {
2279 if (number != (UINT_MAX-1)) {
2283 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2288 Session::region_name (string& result, string base, bool newlevel) const
2295 LockMonitor lm (region_lock, __LINE__, __FILE__);
2297 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2305 /* XXX this is going to be slow. optimize me later */
2310 string::size_type pos;
2312 if ((pos = base.find_last_of ('-')) == string::npos) {
2313 pos = base.find_last_of ('.');
2316 /* pos may be npos, but then we just use entire base */
2318 subbase = base.substr (0, pos);
2321 bool name_taken = true;
2324 LockMonitor lm (region_lock, __LINE__, __FILE__);
2326 for (int n = 1; n < 5000; ++n) {
2329 snprintf (buf, sizeof (buf), ".%d", n);
2334 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2335 if ((*i).second->name() == result) {
2348 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2357 Session::add_region (Region* region)
2359 AudioRegion* ar = 0;
2360 AudioRegion* oar = 0;
2364 LockMonitor lm (region_lock, __LINE__, __FILE__);
2366 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2368 AudioRegionList::iterator x;
2370 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2372 oar = dynamic_cast<AudioRegion*> (x->second);
2374 if (ar->region_list_equivalent (*oar)) {
2379 if (x == audio_regions.end()) {
2381 pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry;
2383 entry.first = region->id();
2386 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2397 fatal << _("programming error: ")
2398 << X_("unknown region type passed to Session::add_region()")
2405 /* mark dirty because something has changed even if we didn't
2406 add the region to the region list.
2412 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2413 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2414 AudioRegionAdded (ar); /* EMIT SIGNAL */
2419 Session::region_changed (Change what_changed, Region* region)
2421 if (what_changed & Region::HiddenChanged) {
2422 /* relay hidden changes */
2423 RegionHiddenChange (region);
2428 Session::region_renamed (Region* region)
2430 add_region (region);
2434 Session::remove_region (Region* region)
2436 AudioRegionList::iterator i;
2437 AudioRegion* ar = 0;
2438 bool removed = false;
2441 LockMonitor lm (region_lock, __LINE__, __FILE__);
2443 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2444 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2445 audio_regions.erase (i);
2449 fatal << _("programming error: ")
2450 << X_("unknown region type passed to Session::remove_region()")
2456 /* mark dirty because something has changed even if we didn't
2457 remove the region from the region list.
2463 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2468 Session::find_whole_file_parent (AudioRegion& child)
2470 AudioRegionList::iterator i;
2471 AudioRegion* region;
2472 LockMonitor lm (region_lock, __LINE__, __FILE__);
2474 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2476 region = (*i).second;
2478 if (region->whole_file()) {
2480 if (child.source_equivalent (*region)) {
2490 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2492 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2496 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2500 pl->get_region_list_equivalent_regions (region, result);
2505 Session::destroy_region (Region* region)
2507 AudioRegion* aregion;
2509 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2513 if (aregion->playlist()) {
2514 aregion->playlist()->destroy_region (region);
2517 vector<Source*> srcs;
2519 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2520 srcs.push_back (&aregion->source (n));
2523 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2525 if ((*i)->use_cnt() == 0) {
2526 (*i)->mark_for_remove ();
2535 Session::destroy_regions (list<Region*> regions)
2537 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2538 destroy_region (*i);
2544 Session::remove_last_capture ()
2548 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2550 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2551 list<Region*>& l = (*i)->last_capture_regions();
2554 r.insert (r.end(), l.begin(), l.end());
2559 destroy_regions (r);
2564 Session::remove_region_from_region_list (Region& r)
2570 /* Source Management */
2573 Session::add_source (Source* source)
2575 pair<SourceList::key_type, SourceList::mapped_type> entry;
2578 LockMonitor lm (source_lock, __LINE__, __FILE__);
2579 entry.first = source->id();
2580 entry.second = source;
2581 sources.insert (entry);
2584 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2587 SourceAdded (source); /* EMIT SIGNAL */
2591 Session::remove_source (Source* source)
2593 SourceList::iterator i;
2596 LockMonitor lm (source_lock, __LINE__, __FILE__);
2598 if ((i = sources.find (source->id())) != sources.end()) {
2603 if (!_state_of_the_state & InCleanup) {
2605 /* save state so we don't end up with a session file
2606 referring to non-existent sources.
2609 save_state (_current_snapshot_name);
2612 SourceRemoved(source); /* EMIT SIGNAL */
2616 Session::get_source (ARDOUR::id_t id)
2618 LockMonitor lm (source_lock, __LINE__, __FILE__);
2619 SourceList::iterator i;
2622 if ((i = sources.find (id)) != sources.end()) {
2623 source = (*i).second;
2630 Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
2634 char buf[PATH_MAX+1];
2635 const uint32_t limit = 10000;
2639 legalized = legalize_for_path (ds.name());
2641 /* find a "version" of the file name that doesn't exist in
2642 any of the possible directories.
2645 for (cnt = 1; cnt <= limit; ++cnt) {
2647 vector<space_and_path>::iterator i;
2648 uint32_t existing = 0;
2650 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2653 spath += sound_dir_name;
2657 if (ds.n_channels() < 2) {
2658 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2659 } else if (ds.n_channels() == 2) {
2661 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2663 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2665 } else if (ds.n_channels() < 26) {
2666 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2668 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2671 if (access (buf, F_OK) == 0) {
2676 if (existing == 0) {
2682 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, ds.name()) << endmsg;
2683 throw failed_constructor();
2686 /* we now have a unique name for the file, but figure out where to
2692 spath = discover_best_sound_dir ();
2694 string::size_type pos = foo.find_last_of ('/');
2696 if (pos == string::npos) {
2699 spath += foo.substr (pos + 1);
2702 /* this might throw failed_constructor(), which is OK */
2705 return new DestructiveFileSource (spath, frame_rate());
2707 return new FileSource (spath, frame_rate());
2711 /* Playlist management */
2714 Session::get_playlist (string name)
2718 if ((ret = playlist_by_name (name)) == 0) {
2719 ret = new AudioPlaylist (*this, name);
2726 Session::playlist_by_name (string name)
2728 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2729 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2730 if ((*i)->name() == name) {
2734 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2735 if ((*i)->name() == name) {
2743 Session::add_playlist (Playlist* playlist)
2745 if (playlist->hidden()) {
2750 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2751 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2752 playlists.insert (playlists.begin(), playlist);
2754 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2755 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2761 PlaylistAdded (playlist); /* EMIT SIGNAL */
2765 Session::track_playlist (Playlist* pl, bool inuse)
2767 PlaylistList::iterator x;
2770 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2773 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2775 unused_playlists.insert (pl);
2777 if ((x = playlists.find (pl)) != playlists.end()) {
2778 playlists.erase (x);
2783 //cerr << "shifting playlist to used: " << pl->name() << endl;
2785 playlists.insert (pl);
2787 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2788 unused_playlists.erase (x);
2795 Session::remove_playlist (Playlist* playlist)
2797 if (_state_of_the_state & Deletion) {
2802 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2803 // cerr << "removing playlist: " << playlist->name() << endl;
2805 PlaylistList::iterator i;
2807 i = find (playlists.begin(), playlists.end(), playlist);
2809 if (i != playlists.end()) {
2810 playlists.erase (i);
2813 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
2814 if (i != unused_playlists.end()) {
2815 unused_playlists.erase (i);
2822 PlaylistRemoved (playlist); /* EMIT SIGNAL */
2826 Session::set_audition (AudioRegion* r)
2828 pending_audition_region = r;
2829 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
2830 schedule_butler_transport_work ();
2834 Session::non_realtime_set_audition ()
2836 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
2837 auditioner->audition_current_playlist ();
2838 } else if (pending_audition_region) {
2839 auditioner->audition_region (*pending_audition_region);
2841 pending_audition_region = 0;
2842 AuditionActive (true); /* EMIT SIGNAL */
2846 Session::audition_playlist ()
2848 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
2849 ev->set_ptr ((void*) 0xfeedface);
2854 Session::audition_region (AudioRegion& r)
2856 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
2862 Session::cancel_audition ()
2864 if (auditioner->active()) {
2865 auditioner->cancel_audition ();
2866 AuditionActive (false); /* EMIT SIGNAL */
2871 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
2873 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
2877 Session::remove_empty_sounds ()
2880 PathScanner scanner;
2885 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
2887 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
2889 if (FileSource::is_empty (*(*i))) {
2891 unlink ((*i)->c_str());
2893 string peak_path = peak_path_from_audio_path (**i);
2894 unlink (peak_path.c_str());
2900 delete possible_audiofiles;
2904 Session::is_auditioning () const
2906 /* can be called before we have an auditioner object */
2908 return auditioner->active();
2916 Session::peak_path_from_audio_path (string audio_path)
2918 /* XXX hardly bombproof! fix me */
2922 res = PBD::dirname (audio_path);
2923 res = PBD::dirname (res);
2925 res += peak_dir_name;
2927 res += PBD::basename_nosuffix (audio_path);
2934 Session::old_peak_path_from_audio_path (string audio_path)
2936 /* This is a hangover from when audio and peak files
2937 lived in the same directory. We need it to to
2938 be able to open old sessions.
2941 /* XXX hardly bombproof! fix me */
2943 string res = audio_path.substr (0, audio_path.find_last_of ('.'));
2949 Session::set_all_solo (bool yn)
2952 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2954 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2955 if (!(*i)->hidden()) {
2956 (*i)->set_solo (yn, this);
2965 Session::set_all_mute (bool yn)
2968 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2970 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2971 if (!(*i)->hidden()) {
2972 (*i)->set_mute (yn, this);
2981 Session::n_diskstreams () const
2983 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2986 for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2987 if (!(*i)->hidden()) {
2995 Session::foreach_diskstream (void (DiskStream::*func)(void))
2997 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2998 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2999 if (!(*i)->hidden()) {
3006 Session::graph_reordered ()
3008 /* don't do this stuff if we are setting up connections
3009 from a set_state() call.
3012 if (_state_of_the_state & InitialConnecting) {
3016 RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3017 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3021 /* force all diskstreams to update their capture offset values to
3022 reflect any changes in latencies within the graph.
3025 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3026 (*i)->set_capture_offset ();
3031 Session::record_disenable_all ()
3033 record_enable_change_all (false);
3037 Session::record_enable_all ()
3039 record_enable_change_all (true);
3043 Session::record_enable_change_all (bool yn)
3045 RWLockMonitor lm1 (route_lock, false, __LINE__, __FILE__);
3047 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3050 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3051 at->set_record_enable (yn, this);
3055 /* since we don't keep rec-enable state, don't mark session dirty */
3059 Session::add_redirect (Redirect* redirect)
3063 PortInsert* port_insert;
3064 PluginInsert* plugin_insert;
3066 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3067 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3068 _port_inserts.insert (_port_inserts.begin(), port_insert);
3069 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3070 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3072 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3075 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3076 _sends.insert (_sends.begin(), send);
3078 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3082 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3088 Session::remove_redirect (Redirect* redirect)
3092 PortInsert* port_insert;
3093 PluginInsert* plugin_insert;
3095 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3096 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3097 _port_inserts.remove (port_insert);
3098 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3099 _plugin_inserts.remove (plugin_insert);
3101 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3104 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3105 _sends.remove (send);
3107 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3115 Session::available_capture_duration ()
3117 const double scale = 4096.0 / sizeof (Sample);
3119 if (_total_free_4k_blocks * scale > (double) max_frames) {
3123 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3127 Session::add_connection (ARDOUR::Connection* connection)
3130 LockMonitor (connection_lock, __LINE__, __FILE__);
3131 _connections.push_back (connection);
3134 ConnectionAdded (connection); /* EMIT SIGNAL */
3140 Session::remove_connection (ARDOUR::Connection* connection)
3142 bool removed = false;
3145 LockMonitor (connection_lock, __LINE__, __FILE__);
3146 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3148 if (i != _connections.end()) {
3149 _connections.erase (i);
3155 ConnectionRemoved (connection); /* EMIT SIGNAL */
3161 ARDOUR::Connection *
3162 Session::connection_by_name (string name) const
3164 LockMonitor lm (connection_lock, __LINE__, __FILE__);
3166 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3167 if ((*i)->name() == name) {
3176 Session::set_edit_mode (EditMode mode)
3181 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3183 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3184 (*i)->set_edit_mode (mode);
3189 ControlChanged (EditingMode); /* EMIT SIGNAL */
3193 Session::tempo_map_changed (Change ignored)
3200 Session::ensure_passthru_buffers (uint32_t howmany)
3202 while (howmany > _passthru_buffers.size()) {
3204 #ifdef NO_POSIX_MEMALIGN
3205 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3207 posix_memalign((void **)&p,16,current_block_size * 4);
3209 _passthru_buffers.push_back (p);
3213 #ifdef NO_POSIX_MEMALIGN
3214 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3216 posix_memalign((void **)&p,16,current_block_size * 4);
3218 memset (p, 0, sizeof (Sample) * current_block_size);
3219 _silent_buffers.push_back (p);
3222 allocate_pan_automation_buffers (current_block_size, howmany, false);
3226 Session::next_send_name ()
3229 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3234 Session::next_insert_name ()
3237 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3241 /* Named Selection management */
3244 Session::named_selection_by_name (string name)
3246 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3247 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3248 if ((*i)->name == name) {
3256 Session::add_named_selection (NamedSelection* named_selection)
3259 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3260 named_selections.insert (named_selections.begin(), named_selection);
3265 NamedSelectionAdded (); /* EMIT SIGNAL */
3269 Session::remove_named_selection (NamedSelection* named_selection)
3271 bool removed = false;
3274 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3276 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3278 if (i != named_selections.end()) {
3280 named_selections.erase (i);
3287 NamedSelectionRemoved (); /* EMIT SIGNAL */
3292 Session::reset_native_file_format ()
3294 // jlc - WHY take routelock?
3295 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3296 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3298 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3299 (*i)->reset_write_sources (false);
3304 Session::route_name_unique (string n) const
3306 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3308 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3309 if ((*i)->name() == n) {
3318 Session::remove_file_source (FileSource& fs)
3320 return fs.move_to_trash (dead_sound_dir_name);
3324 Session::n_playlists () const
3326 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3327 return playlists.size();
3331 Session::set_solo_model (SoloModel sm)
3333 if (sm != _solo_model) {
3335 ControlChanged (SoloingModel);
3341 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3343 if (!force && howmany <= _npan_buffers) {
3347 if (_pan_automation_buffer) {
3349 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3350 delete [] _pan_automation_buffer[i];
3353 delete [] _pan_automation_buffer;
3356 _pan_automation_buffer = new pan_t*[howmany];
3358 for (uint32_t i = 0; i < howmany; ++i) {
3359 _pan_automation_buffer[i] = new pan_t[nframes];
3362 _npan_buffers = howmany;
3366 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3368 Stateful::add_instant_xml (node, dir);
3369 Config->add_instant_xml (node, Config->get_user_ardour_path());
3373 Session::freeze (InterThreadInfo& itt)
3375 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3377 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3381 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3382 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3393 Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len, bool overwrite, vector<Source*>& srcs,
3394 InterThreadInfo& itt)
3398 FileSource* fsource;
3400 char buf[PATH_MAX+1];
3403 jack_nframes_t position;
3404 jack_nframes_t this_chunk;
3405 jack_nframes_t to_do;
3406 vector<Sample*> buffers;
3407 const jack_nframes_t chunk_size = (256 * 1024)/4;
3409 atomic_set (&processing_prohibited, 1);
3411 /* call tree *MUST* hold route_lock */
3413 if ((playlist = track.disk_stream().playlist()) == 0) {
3417 /* external redirects will be a problem */
3419 if (track.has_external_redirects()) {
3423 nchans = track.disk_stream().n_channels();
3425 dir = discover_best_sound_dir ();
3427 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3429 for (x = 0; x < 99999; ++x) {
3430 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3431 if (access (buf, F_OK) != 0) {
3437 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3442 fsource = new FileSource (buf, frame_rate());
3445 catch (failed_constructor& err) {
3446 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3450 srcs.push_back(fsource);
3453 /* XXX need to flush all redirects */
3458 /* create a set of reasonably-sized buffers */
3460 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3462 #ifdef NO_POSIX_MEMALIGN
3463 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3465 posix_memalign((void **)&b,16,chunk_size * 4);
3467 buffers.push_back (b);
3470 while (to_do && !itt.cancel) {
3472 this_chunk = min (to_do, chunk_size);
3474 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3479 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3480 if ((*src)->write (buffers[n], this_chunk) != this_chunk) {
3485 start += this_chunk;
3486 to_do -= this_chunk;
3488 itt.progress = (float) (1.0 - ((double) to_do / len));
3497 xnow = localtime (&now);
3499 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3500 dynamic_cast<FileSource*>((*src))->update_header (position, *xnow, now);
3503 /* build peakfile for new source */
3505 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3506 dynamic_cast<FileSource*>(*src)->build_peaks ();
3514 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3515 dynamic_cast<FileSource*>(*src)->mark_for_remove ();
3520 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3524 atomic_set (&processing_prohibited, 0);
3532 Session::get_silent_buffers (uint32_t howmany)
3534 for (uint32_t i = 0; i < howmany; ++i) {
3535 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3537 return _silent_buffers;
3541 Session::ntracks () const
3544 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3546 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3547 if (dynamic_cast<AudioTrack*> (*i)) {
3556 Session::nbusses () const
3559 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3561 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3562 if (dynamic_cast<AudioTrack*> (*i) == 0) {
3571 Session::set_layer_model (LayerModel lm)
3573 if (lm != layer_model) {
3576 ControlChanged (LayeringModel);
3581 Session::set_xfade_model (CrossfadeModel xm)
3583 if (xm != xfade_model) {
3586 ControlChanged (CrossfadingModel);