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 for (map<RunContext,char*>::iterator i = _conversion_buffers.begin(); i != _conversion_buffers.end(); ++i) {
393 delete [] (i->second);
396 #undef TRACK_DESTRUCTION
397 #ifdef TRACK_DESTRUCTION
398 cerr << "delete named selections\n";
399 #endif /* TRACK_DESTRUCTION */
400 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
401 NamedSelectionList::iterator tmp;
410 #ifdef TRACK_DESTRUCTION
411 cerr << "delete playlists\n";
412 #endif /* TRACK_DESTRUCTION */
413 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
414 PlaylistList::iterator tmp;
424 #ifdef TRACK_DESTRUCTION
425 cerr << "delete audio regions\n";
426 #endif /* TRACK_DESTRUCTION */
427 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
428 AudioRegionList::iterator tmp;
438 #ifdef TRACK_DESTRUCTION
439 cerr << "delete routes\n";
440 #endif /* TRACK_DESTRUCTION */
441 for (RouteList::iterator i = routes.begin(); i != routes.end(); ) {
442 RouteList::iterator tmp;
449 #ifdef TRACK_DESTRUCTION
450 cerr << "delete diskstreams\n";
451 #endif /* TRACK_DESTRUCTION */
452 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
453 DiskStreamList::iterator tmp;
463 #ifdef TRACK_DESTRUCTION
464 cerr << "delete sources\n";
465 #endif /* TRACK_DESTRUCTION */
466 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
467 SourceList::iterator tmp;
477 #ifdef TRACK_DESTRUCTION
478 cerr << "delete mix groups\n";
479 #endif /* TRACK_DESTRUCTION */
480 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
481 list<RouteGroup*>::iterator tmp;
491 #ifdef TRACK_DESTRUCTION
492 cerr << "delete edit groups\n";
493 #endif /* TRACK_DESTRUCTION */
494 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
495 list<RouteGroup*>::iterator tmp;
505 #ifdef TRACK_DESTRUCTION
506 cerr << "delete connections\n";
507 #endif /* TRACK_DESTRUCTION */
508 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
509 ConnectionList::iterator tmp;
519 if (butler_mixdown_buffer) {
520 delete [] butler_mixdown_buffer;
523 if (butler_gain_buffer) {
524 delete [] butler_gain_buffer;
527 Crossfade::set_buffer_size (0);
539 Session::set_worst_io_latencies (bool take_lock)
541 _worst_output_latency = 0;
542 _worst_input_latency = 0;
544 if (!_engine.connected()) {
549 route_lock.read_lock ();
552 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
553 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
554 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
558 route_lock.unlock ();
563 Session::when_engine_running ()
565 string first_physical_output;
567 /* we don't want to run execute this again */
569 first_time_running.disconnect ();
571 set_block_size (_engine.frames_per_cycle());
572 set_frame_rate (_engine.frame_rate());
574 /* every time we reconnect, recompute worst case output latencies */
576 _engine.Running.connect (sigc::bind (mem_fun (*this, &Session::set_worst_io_latencies), true));
578 if (synced_to_jack()) {
579 _engine.transport_stop ();
582 if (Config->get_jack_time_master()) {
583 _engine.transport_locate (_transport_frame);
591 _click_io = new ClickIO (*this, "click", 0, 0, -1, -1);
593 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
595 /* existing state for Click */
597 if (_click_io->set_state (*child->children().front()) == 0) {
599 _clicking = click_requested;
603 error << _("could not setup Click I/O") << endmsg;
609 /* default state for Click */
611 first_physical_output = _engine.get_nth_physical_output (0);
613 if (first_physical_output.length()) {
614 if (_click_io->add_output_port (first_physical_output, this)) {
615 // relax, even though its an error
617 _clicking = click_requested;
623 catch (failed_constructor& err) {
624 error << _("cannot setup Click I/O") << endmsg;
627 set_worst_io_latencies (true);
630 ControlChanged (Clicking); /* EMIT SIGNAL */
633 if (auditioner == 0) {
635 /* we delay creating the auditioner till now because
636 it makes its own connections to ports named
637 in the ARDOUR_RC config file. the engine has
638 to be running for this to work.
642 auditioner = new Auditioner (*this);
645 catch (failed_constructor& err) {
646 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
650 /* Create a set of Connection objects that map
651 to the physical outputs currently available
656 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
658 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
660 Connection* c = new OutputConnection (buf, true);
663 c->add_connection (0, _engine.get_nth_physical_output (np));
668 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
670 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
672 Connection* c = new InputConnection (buf, true);
675 c->add_connection (0, _engine.get_nth_physical_input (np));
682 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
684 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
686 Connection* c = new OutputConnection (buf, true);
690 c->add_connection (0, _engine.get_nth_physical_output (np));
691 c->add_connection (1, _engine.get_nth_physical_output (np+1));
696 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
698 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
700 Connection* c = new InputConnection (buf, true);
704 c->add_connection (0, _engine.get_nth_physical_input (np));
705 c->add_connection (1, _engine.get_nth_physical_input (np+1));
714 /* create master/control ports */
719 /* force the master to ignore any later call to this */
721 if (_master_out->pending_state_node) {
722 _master_out->ports_became_legal();
725 /* no panner resets till we are through */
727 _master_out->defer_pan_reset ();
729 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
730 if (_master_out->add_input_port ("", this)) {
731 error << _("cannot setup master inputs")
737 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
738 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
739 error << _("cannot setup master outputs")
746 _master_out->allow_pan_reset ();
750 Connection* c = new OutputConnection (_("Master Out"), true);
752 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
754 c->add_connection ((int) n, _master_out->input(n)->name());
761 /* catch up on send+insert cnts */
765 for (slist<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
768 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
769 if (id > insert_cnt) {
777 for (slist<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
780 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
787 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
789 /* hook us up to the engine */
791 _engine.set_session (this);
793 _state_of_the_state = Clean;
795 DirtyChanged (); /* EMIT SIGNAL */
799 Session::hookup_io ()
801 /* stop graph reordering notifications from
802 causing resorts, etc.
805 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
807 /* Tell all IO objects to create their ports */
814 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
815 if (_control_out->add_input_port ("", this)) {
816 error << _("cannot setup control inputs")
822 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
823 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
824 error << _("cannot set up master outputs")
832 /* Tell all IO objects to connect themselves together */
834 IO::enable_connecting ();
836 /* Now reset all panners */
838 IO::reset_panners ();
840 /* Anyone who cares about input state, wake up and do something */
842 IOConnectionsComplete (); /* EMIT SIGNAL */
844 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
846 /* now handle the whole enchilada as if it was one
852 /* update mixer solo state */
858 Session::playlist_length_changed (Playlist* pl)
860 /* we can't just increase end_location->end() if pl->get_maximum_extent()
861 if larger. if the playlist used to be the longest playlist,
862 and its now shorter, we have to decrease end_location->end(). hence,
863 we have to iterate over all diskstreams and check the
864 playlists currently in use.
870 Session::diskstream_playlist_changed (DiskStream* dstream)
874 if ((playlist = dstream->playlist()) != 0) {
875 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
878 /* see comment in playlist_length_changed () */
883 Session::record_enabling_legal () const
885 /* this used to be in here, but survey says.... we don't need to restrict it */
886 // if (record_status() == Recording) {
897 Session::set_auto_play (bool yn)
899 if (auto_play != yn) {
902 ControlChanged (AutoPlay);
907 Session::set_auto_return (bool yn)
909 if (auto_return != yn) {
912 ControlChanged (AutoReturn);
917 Session::set_crossfades_active (bool yn)
919 if (crossfades_active != yn) {
920 crossfades_active = yn;
922 ControlChanged (CrossFadesActive);
927 Session::set_do_not_record_plugins (bool yn)
929 if (do_not_record_plugins != yn) {
930 do_not_record_plugins = yn;
932 ControlChanged (RecordingPlugins);
937 Session::set_auto_input (bool yn)
939 if (auto_input != yn) {
942 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
943 /* auto-input only makes a difference if we're rolling */
945 /* Even though this can called from RT context we are using
946 a non-tentative rwlock here, because the action must occur.
947 The rarity and short potential lock duration makes this "OK"
949 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
950 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
951 if ((*i)->record_enabled ()) {
952 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
953 (*i)->monitor_input (!auto_input);
959 ControlChanged (AutoInput);
964 Session::reset_input_monitor_state ()
966 if (transport_rolling()) {
967 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
968 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
969 if ((*i)->record_enabled ()) {
970 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
971 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
975 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
976 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
977 if ((*i)->record_enabled ()) {
978 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
979 (*i)->monitor_input (Config->get_use_hardware_monitoring());
987 Session::set_input_auto_connect (bool yn)
990 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
992 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
998 Session::get_input_auto_connect () const
1000 return (input_auto_connect & AutoConnectPhysical);
1004 Session::set_output_auto_connect (AutoConnectOption aco)
1006 output_auto_connect = aco;
1011 Session::auto_punch_start_changed (Location* location)
1013 replace_event (Event::PunchIn, location->start());
1015 if (get_record_enabled() && get_punch_in()) {
1016 /* capture start has been changed, so save new pending state */
1017 save_state ("", true);
1022 Session::auto_punch_end_changed (Location* location)
1024 jack_nframes_t when_to_stop = location->end();
1025 // when_to_stop += _worst_output_latency + _worst_input_latency;
1026 replace_event (Event::PunchOut, when_to_stop);
1030 Session::auto_punch_changed (Location* location)
1032 jack_nframes_t when_to_stop = location->end();
1034 replace_event (Event::PunchIn, location->start());
1035 //when_to_stop += _worst_output_latency + _worst_input_latency;
1036 replace_event (Event::PunchOut, when_to_stop);
1040 Session::auto_loop_changed (Location* location)
1042 replace_event (Event::AutoLoop, location->end(), location->start());
1044 if (transport_rolling() && get_auto_loop()) {
1046 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1048 if (_transport_frame > location->end()) {
1049 // relocate to beginning of loop
1050 clear_events (Event::LocateRoll);
1052 request_locate (location->start(), true);
1055 else if (seamless_loop && !loop_changing) {
1057 // schedule a locate-roll to refill the diskstreams at the
1058 // previous loop end
1059 loop_changing = true;
1061 if (location->end() > last_loopend) {
1062 clear_events (Event::LocateRoll);
1063 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1070 last_loopend = location->end();
1075 Session::set_auto_punch_location (Location* location)
1079 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1080 auto_punch_start_changed_connection.disconnect();
1081 auto_punch_end_changed_connection.disconnect();
1082 auto_punch_changed_connection.disconnect();
1083 existing->set_auto_punch (false, this);
1084 remove_event (existing->start(), Event::PunchIn);
1085 clear_events (Event::PunchOut);
1086 auto_punch_location_changed (0);
1091 if (location == 0) {
1095 if (location->end() <= location->start()) {
1096 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1100 auto_punch_start_changed_connection.disconnect();
1101 auto_punch_end_changed_connection.disconnect();
1102 auto_punch_changed_connection.disconnect();
1104 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1105 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1106 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1108 location->set_auto_punch (true, this);
1109 auto_punch_location_changed (location);
1113 Session::set_punch_in (bool yn)
1115 if (punch_in == yn) {
1121 if ((location = _locations.auto_punch_location()) != 0) {
1122 if ((punch_in = yn) == true) {
1123 replace_event (Event::PunchIn, location->start());
1125 remove_event (location->start(), Event::PunchIn);
1130 ControlChanged (PunchIn); /* EMIT SIGNAL */
1134 Session::set_punch_out (bool yn)
1136 if (punch_out == yn) {
1142 if ((location = _locations.auto_punch_location()) != 0) {
1143 if ((punch_out = yn) == true) {
1144 replace_event (Event::PunchOut, location->end());
1146 clear_events (Event::PunchOut);
1151 ControlChanged (PunchOut); /* EMIT SIGNAL */
1155 Session::set_auto_loop_location (Location* location)
1159 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1160 auto_loop_start_changed_connection.disconnect();
1161 auto_loop_end_changed_connection.disconnect();
1162 auto_loop_changed_connection.disconnect();
1163 existing->set_auto_loop (false, this);
1164 remove_event (existing->end(), Event::AutoLoop);
1165 auto_loop_location_changed (0);
1170 if (location == 0) {
1174 if (location->end() <= location->start()) {
1175 error << _("Session: you can't use a mark for auto loop") << endmsg;
1179 last_loopend = location->end();
1181 auto_loop_start_changed_connection.disconnect();
1182 auto_loop_end_changed_connection.disconnect();
1183 auto_loop_changed_connection.disconnect();
1185 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1186 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1187 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1189 location->set_auto_loop (true, this);
1190 auto_loop_location_changed (location);
1194 Session::locations_added (Location* ignored)
1200 Session::locations_changed ()
1202 _locations.apply (*this, &Session::handle_locations_changed);
1206 Session::handle_locations_changed (Locations::LocationList& locations)
1208 Locations::LocationList::iterator i;
1210 bool set_loop = false;
1211 bool set_punch = false;
1213 for (i = locations.begin(); i != locations.end(); ++i) {
1217 if (location->is_auto_punch()) {
1218 set_auto_punch_location (location);
1221 if (location->is_auto_loop()) {
1222 set_auto_loop_location (location);
1229 set_auto_loop_location (0);
1232 set_auto_punch_location (0);
1239 Session::enable_record ()
1241 /* XXX really atomic compare+swap here */
1242 if (atomic_read (&_record_status) != Recording) {
1243 atomic_set (&_record_status, Recording);
1244 _last_record_location = _transport_frame;
1245 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1247 if (Config->get_use_hardware_monitoring() && auto_input) {
1248 /* Even though this can be called from RT context we are using
1249 a non-tentative rwlock here, because the action must occur.
1250 The rarity and short potential lock duration makes this "OK"
1252 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1254 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1255 if ((*i)->record_enabled ()) {
1256 (*i)->monitor_input (true);
1261 RecordStateChanged ();
1266 Session::disable_record (bool force)
1270 if ((rs = (RecordState) atomic_read (&_record_status)) != Disabled) {
1272 if (!Config->get_latched_record_enable () || force) {
1273 atomic_set (&_record_status, Disabled);
1275 if (rs == Recording) {
1276 atomic_set (&_record_status, Enabled);
1280 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1282 if (Config->get_use_hardware_monitoring() && auto_input) {
1283 /* Even though this can be called from RT context we are using
1284 a non-tentative rwlock here, because the action must occur.
1285 The rarity and short potential lock duration makes this "OK"
1287 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1289 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1290 if ((*i)->record_enabled ()) {
1291 (*i)->monitor_input (false);
1296 RecordStateChanged (); /* emit signal */
1297 remove_pending_capture_state ();
1302 Session::step_back_from_record ()
1304 atomic_set (&_record_status, Enabled);
1306 if (Config->get_use_hardware_monitoring()) {
1307 /* Even though this can be called from RT context we are using
1308 a non-tentative rwlock here, because the action must occur.
1309 The rarity and short potential lock duration makes this "OK"
1311 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1313 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1314 if (auto_input && (*i)->record_enabled ()) {
1315 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1316 (*i)->monitor_input (false);
1323 Session::maybe_enable_record ()
1325 atomic_set (&_record_status, Enabled);
1327 /* XXX this save should really happen in another thread. its needed so that
1328 pending capture state can be recovered if we crash.
1331 save_state ("", true);
1333 if (_transport_speed) {
1338 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1339 RecordStateChanged (); /* EMIT SIGNAL */
1346 Session::audible_frame () const
1349 jack_nframes_t offset;
1352 /* the first of these two possible settings for "offset"
1353 mean that the audible frame is stationary until
1354 audio emerges from the latency compensation
1357 the second means that the audible frame is stationary
1358 until audio would emerge from a physical port
1359 in the absence of any plugin latency compensation
1362 offset = _worst_output_latency;
1364 if (offset > current_block_size) {
1365 offset -= current_block_size;
1367 /* XXX is this correct? if we have no external
1368 physical connections and everything is internal
1369 then surely this is zero? still, how
1370 likely is that anyway?
1372 offset = current_block_size;
1375 if (synced_to_jack()) {
1376 tf = _engine.transport_frame();
1378 tf = _transport_frame;
1381 if (_transport_speed == 0) {
1391 if (!non_realtime_work_pending()) {
1395 /* take latency into account */
1404 Session::set_frame_rate (jack_nframes_t frames_per_second)
1406 /** \fn void Session::set_frame_size(jack_nframes_t)
1407 the AudioEngine object that calls this guarantees
1408 that it will not be called while we are also in
1409 ::process(). Its fine to do things that block
1413 _current_frame_rate = frames_per_second;
1414 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1416 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1420 /* XXX need to reset/reinstantiate all LADSPA plugins */
1424 Session::set_block_size (jack_nframes_t nframes)
1426 /* the AudioEngine guarantees
1427 that it will not be called while we are also in
1428 ::process(). It is therefore fine to do things that block
1433 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1434 RWLockMonitor dsm (diskstream_lock, false, __LINE__, __FILE__);
1435 vector<Sample*>::iterator i;
1438 current_block_size = nframes;
1440 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1444 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1448 _passthru_buffers.clear ();
1449 _silent_buffers.clear ();
1451 ensure_passthru_buffers (np);
1453 if (_gain_automation_buffer) {
1454 delete [] _gain_automation_buffer;
1456 _gain_automation_buffer = new gain_t[nframes];
1458 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1460 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1461 (*i)->set_block_size (nframes);
1464 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1465 (*i)->set_block_size (nframes);
1468 set_worst_io_latencies (false);
1473 Session::set_default_fade (float steepness, float fade_msecs)
1476 jack_nframes_t fade_frames;
1478 /* Don't allow fade of less 1 frame */
1480 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1487 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1491 default_fade_msecs = fade_msecs;
1492 default_fade_steepness = steepness;
1495 // jlc, WTF is this!
1496 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1497 AudioRegion::set_default_fade (steepness, fade_frames);
1502 /* XXX have to do this at some point */
1503 /* foreach region using default fade, reset, then
1504 refill_all_diskstream_buffers ();
1509 struct RouteSorter {
1510 bool operator() (Route* r1, Route* r2) {
1511 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1513 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1516 if (r1->fed_by.empty()) {
1517 if (r2->fed_by.empty()) {
1518 /* no ardour-based connections inbound to either route. just use signal order */
1519 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1521 /* r2 has connections, r1 does not; run r1 early */
1525 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1532 trace_terminal (Route* r1, Route* rbase)
1536 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1537 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1541 /* make a copy of the existing list of routes that feed r1 */
1543 set<Route *> existing = r1->fed_by;
1545 /* for each route that feeds r1, recurse, marking it as feeding
1549 for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
1552 /* r2 is a route that feeds r1 which somehow feeds base. mark
1553 base as being fed by r2
1556 rbase->fed_by.insert (r2);
1560 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1564 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1568 /* now recurse, so that we can mark base as being fed by
1569 all routes that feed r2
1572 trace_terminal (r2, rbase);
1579 Session::resort_routes (void* src)
1581 /* don't do anything here with signals emitted
1582 by Routes while we are being destroyed.
1585 if (_state_of_the_state & Deletion) {
1589 /* Caller MUST hold the route_lock */
1591 RouteList::iterator i, j;
1593 for (i = routes.begin(); i != routes.end(); ++i) {
1595 (*i)->fed_by.clear ();
1597 for (j = routes.begin(); j != routes.end(); ++j) {
1599 /* although routes can feed themselves, it will
1600 cause an endless recursive descent if we
1601 detect it. so don't bother checking for
1609 if ((*j)->feeds (*i)) {
1610 (*i)->fed_by.insert (*j);
1615 for (i = routes.begin(); i != routes.end(); ++i) {
1616 trace_terminal (*i, *i);
1623 cerr << "finished route resort\n";
1625 for (i = routes.begin(); i != routes.end(); ++i) {
1626 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1634 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1637 char track_name[32];
1639 uint32_t channels_used = 0;
1641 uint32_t nphysical_in;
1642 uint32_t nphysical_out;
1644 /* count existing audio tracks */
1647 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1648 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1649 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1650 if (!(*i)->hidden()) {
1652 channels_used += (*i)->n_inputs();
1658 /* check for duplicate route names, since we might have pre-existing
1659 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1660 save, close,restart,add new route - first named route is now
1665 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1666 if (route_by_name (track_name) == 0) {
1671 } while (n < (UINT_MAX-1));
1673 if (input_auto_connect & AutoConnectPhysical) {
1674 nphysical_in = n_physical_inputs;
1679 if (output_auto_connect & AutoConnectPhysical) {
1680 nphysical_out = n_physical_outputs;
1686 track = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1688 if (track->ensure_io (input_channels, output_channels, false, this)) {
1689 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1690 input_channels, output_channels)
1695 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1699 if (input_auto_connect & AutoConnectPhysical) {
1700 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1703 if (port.length() && track->connect_input (track->input (x), port, this)) {
1709 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1713 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1714 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1715 } else if (output_auto_connect & AutoConnectMaster) {
1717 port = _master_out->input (x%_master_out->n_inputs())->name();
1721 if (port.length() && track->connect_output (track->output (x), port, this)) {
1727 vector<string> cports;
1728 uint32_t ni = _control_out->n_inputs();
1730 for (n = 0; n < ni; ++n) {
1731 cports.push_back (_control_out->input(n)->name());
1734 track->set_control_outs (cports);
1737 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1741 track->set_remote_control_id (ntracks());
1744 catch (failed_constructor &err) {
1745 error << _("Session: could not create new audio track.") << endmsg;
1753 Session::new_audio_route (int input_channels, int output_channels)
1760 /* count existing audio busses */
1763 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1764 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1765 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1766 if (!(*i)->hidden()) {
1774 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1775 if (route_by_name (bus_name) == 0) {
1780 } while (n < (UINT_MAX-1));
1783 bus = new Route (*this, bus_name, -1, -1, -1, -1);
1785 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1786 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1787 input_channels, output_channels)
1791 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1795 if (input_auto_connect & AutoConnectPhysical) {
1796 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1799 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1804 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1808 if (output_auto_connect & AutoConnectPhysical) {
1809 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1810 } else if (output_auto_connect & AutoConnectMaster) {
1812 port = _master_out->input (x%_master_out->n_inputs())->name();
1816 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1822 vector<string> cports;
1823 uint32_t ni = _control_out->n_inputs();
1825 for (uint32_t n = 0; n < ni; ++n) {
1826 cports.push_back (_control_out->input(n)->name());
1828 bus->set_control_outs (cports);
1834 catch (failed_constructor &err) {
1835 error << _("Session: could not create new route.") << endmsg;
1843 Session::add_route (Route* route)
1846 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1847 routes.push_front (route);
1851 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1852 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1853 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1854 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1856 if (route->master()) {
1857 _master_out = route;
1860 if (route->control()) {
1861 _control_out = route;
1865 save_state (_current_snapshot_name);
1867 RouteAdded (route); /* EMIT SIGNAL */
1871 Session::add_diskstream (DiskStream* dstream)
1873 /* need to do this in case we're rolling at the time, to prevent false underruns */
1874 dstream->do_refill(0, 0, 0);
1877 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1878 diskstreams.push_back (dstream);
1881 /* take a reference to the diskstream, preventing it from
1882 ever being deleted until the session itself goes away,
1883 or chooses to remove it for its own purposes.
1887 dstream->set_block_size (current_block_size);
1889 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1890 /* this will connect to future changes, and check the current length */
1891 diskstream_playlist_changed (dstream);
1893 dstream->prepare ();
1896 save_state (_current_snapshot_name);
1898 DiskStreamAdded (dstream); /* EMIT SIGNAL */
1902 Session::remove_route (Route& route)
1905 RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
1906 routes.remove (&route);
1908 /* deleting the master out seems like a dumb
1909 idea, but its more of a UI policy issue
1913 if (&route == _master_out) {
1917 if (&route == _control_out) {
1920 /* cancel control outs for all routes */
1922 vector<string> empty;
1924 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
1925 (*r)->set_control_outs (empty);
1929 update_route_solo_state ();
1933 RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
1937 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
1938 diskstreams.remove (&at->disk_stream());
1939 at->disk_stream().unref ();
1942 find_current_end ();
1945 update_latency_compensation (false, false);
1948 /* XXX should we disconnect from the Route's signals ? */
1950 save_state (_current_snapshot_name);
1956 Session::route_mute_changed (void* src)
1962 Session::route_solo_changed (void* src, Route* route)
1964 if (solo_update_disabled) {
1969 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1972 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
1974 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1976 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
1980 /* don't mess with busses */
1982 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1988 /* don't mess with tracks */
1990 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1995 if ((*i) != route &&
1996 ((*i)->mix_group () == 0 ||
1997 (*i)->mix_group () != route->mix_group () ||
1998 !route->mix_group ()->is_active())) {
2000 if ((*i)->soloed()) {
2002 /* if its already soloed, and solo latching is enabled,
2003 then leave it as it is.
2006 if (_solo_latched) {
2013 solo_update_disabled = true;
2014 (*i)->set_solo (false, src);
2015 solo_update_disabled = false;
2019 bool something_soloed = false;
2020 bool same_thing_soloed = false;
2021 bool signal = false;
2023 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2024 if ((*i)->soloed()) {
2025 something_soloed = true;
2026 if (dynamic_cast<AudioTrack*>(*i)) {
2028 same_thing_soloed = true;
2033 same_thing_soloed = true;
2041 if (something_soloed != currently_soloing) {
2043 currently_soloing = something_soloed;
2046 modify_solo_mute (is_track, same_thing_soloed);
2049 SoloActive (currently_soloing);
2056 Session::set_solo_latched (bool yn)
2058 if (yn != _solo_latched) {
2061 ControlChanged (SoloLatch);
2066 Session::update_route_solo_state ()
2069 bool is_track = false;
2070 bool signal = false;
2072 /* caller must hold RouteLock */
2074 /* this is where we actually implement solo by changing
2075 the solo mute setting of each track.
2078 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2079 if ((*i)->soloed()) {
2081 if (dynamic_cast<AudioTrack*>(*i)) {
2088 if (mute != currently_soloing) {
2090 currently_soloing = mute;
2093 if (!is_track && !mute) {
2095 /* nothing is soloed */
2097 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2098 (*i)->set_solo_mute (false);
2108 modify_solo_mute (is_track, mute);
2111 SoloActive (currently_soloing);
2116 Session::modify_solo_mute (bool is_track, bool mute)
2118 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2122 /* only alter track solo mute */
2124 if (dynamic_cast<AudioTrack*>(*i)) {
2125 if ((*i)->soloed()) {
2126 (*i)->set_solo_mute (!mute);
2128 (*i)->set_solo_mute (mute);
2134 /* only alter bus solo mute */
2136 if (!dynamic_cast<AudioTrack*>(*i)) {
2138 if ((*i)->soloed()) {
2140 (*i)->set_solo_mute (false);
2144 /* don't mute master or control outs
2145 in response to another bus solo
2148 if ((*i) != _master_out &&
2149 (*i) != _control_out) {
2150 (*i)->set_solo_mute (mute);
2161 Session::catch_up_on_solo ()
2163 /* this is called after set_state() to catch the full solo
2164 state, which can't be correctly determined on a per-route
2165 basis, but needs the global overview that only the session
2168 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2169 update_route_solo_state();
2173 Session::route_by_name (string name)
2175 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2177 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2178 if ((*i)->name() == name) {
2187 Session::find_current_end ()
2189 jack_nframes_t max = 0;
2192 if (_state_of_the_state & Loading) {
2196 /* Don't take the diskstream lock. Caller must have other ways to
2200 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2201 Playlist* pl = (*i)->playlist();
2202 if ((me = pl->get_maximum_extent()) > max) {
2207 if (max > end_location->end()) {
2208 end_location->set_end (max);
2210 DurationChanged(); /* EMIT SIGNAL */
2215 Session::diskstream_by_name (string name)
2217 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2219 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2220 if ((*i)->name() == name) {
2229 Session::diskstream_by_id (id_t id)
2231 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2233 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2234 if ((*i)->id() == id) {
2242 /* AudioRegion management */
2245 Session::new_region_name (string old)
2247 string::size_type last_period;
2249 string::size_type len = old.length() + 64;
2252 if ((last_period = old.find_last_of ('.')) == string::npos) {
2254 /* no period present - add one explicitly */
2257 last_period = old.length() - 1;
2262 number = atoi (old.substr (last_period+1).c_str());
2266 while (number < (UINT_MAX-1)) {
2268 AudioRegionList::const_iterator i;
2273 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2276 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2277 if ((*i).second->name() == sbuf) {
2282 if (i == audio_regions.end()) {
2287 if (number != (UINT_MAX-1)) {
2291 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2296 Session::region_name (string& result, string base, bool newlevel) const
2303 LockMonitor lm (region_lock, __LINE__, __FILE__);
2305 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2313 /* XXX this is going to be slow. optimize me later */
2318 string::size_type pos;
2320 if ((pos = base.find_last_of ('-')) == string::npos) {
2321 pos = base.find_last_of ('.');
2324 /* pos may be npos, but then we just use entire base */
2326 subbase = base.substr (0, pos);
2329 bool name_taken = true;
2332 LockMonitor lm (region_lock, __LINE__, __FILE__);
2334 for (int n = 1; n < 5000; ++n) {
2337 snprintf (buf, sizeof (buf), ".%d", n);
2342 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2343 if ((*i).second->name() == result) {
2356 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2365 Session::add_region (Region* region)
2367 AudioRegion* ar = 0;
2368 AudioRegion* oar = 0;
2372 LockMonitor lm (region_lock, __LINE__, __FILE__);
2374 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2376 AudioRegionList::iterator x;
2378 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2380 oar = dynamic_cast<AudioRegion*> (x->second);
2382 if (ar->region_list_equivalent (*oar)) {
2387 if (x == audio_regions.end()) {
2389 pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry;
2391 entry.first = region->id();
2394 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2405 fatal << _("programming error: ")
2406 << X_("unknown region type passed to Session::add_region()")
2413 /* mark dirty because something has changed even if we didn't
2414 add the region to the region list.
2420 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2421 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2422 AudioRegionAdded (ar); /* EMIT SIGNAL */
2427 Session::region_changed (Change what_changed, Region* region)
2429 if (what_changed & Region::HiddenChanged) {
2430 /* relay hidden changes */
2431 RegionHiddenChange (region);
2436 Session::region_renamed (Region* region)
2438 add_region (region);
2442 Session::remove_region (Region* region)
2444 AudioRegionList::iterator i;
2445 AudioRegion* ar = 0;
2446 bool removed = false;
2449 LockMonitor lm (region_lock, __LINE__, __FILE__);
2451 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2452 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2453 audio_regions.erase (i);
2457 fatal << _("programming error: ")
2458 << X_("unknown region type passed to Session::remove_region()")
2464 /* mark dirty because something has changed even if we didn't
2465 remove the region from the region list.
2471 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2476 Session::find_whole_file_parent (AudioRegion& child)
2478 AudioRegionList::iterator i;
2479 AudioRegion* region;
2480 LockMonitor lm (region_lock, __LINE__, __FILE__);
2482 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2484 region = (*i).second;
2486 if (region->whole_file()) {
2488 if (child.source_equivalent (*region)) {
2498 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2500 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2504 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2508 pl->get_region_list_equivalent_regions (region, result);
2513 Session::destroy_region (Region* region)
2515 AudioRegion* aregion;
2517 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2521 if (aregion->playlist()) {
2522 aregion->playlist()->destroy_region (region);
2525 vector<Source*> srcs;
2527 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2528 srcs.push_back (&aregion->source (n));
2531 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2533 if ((*i)->use_cnt() == 0) {
2534 (*i)->mark_for_remove ();
2543 Session::destroy_regions (list<Region*> regions)
2545 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2546 destroy_region (*i);
2552 Session::remove_last_capture ()
2556 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2558 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2559 list<Region*>& l = (*i)->last_capture_regions();
2562 r.insert (r.end(), l.begin(), l.end());
2567 destroy_regions (r);
2572 Session::remove_region_from_region_list (Region& r)
2578 /* Source Management */
2581 Session::add_source (Source* source)
2583 pair<SourceList::key_type, SourceList::mapped_type> entry;
2586 LockMonitor lm (source_lock, __LINE__, __FILE__);
2587 entry.first = source->id();
2588 entry.second = source;
2589 sources.insert (entry);
2592 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2595 SourceAdded (source); /* EMIT SIGNAL */
2599 Session::remove_source (Source* source)
2601 SourceList::iterator i;
2604 LockMonitor lm (source_lock, __LINE__, __FILE__);
2606 if ((i = sources.find (source->id())) != sources.end()) {
2611 if (!_state_of_the_state & InCleanup) {
2613 /* save state so we don't end up with a session file
2614 referring to non-existent sources.
2617 save_state (_current_snapshot_name);
2620 SourceRemoved(source); /* EMIT SIGNAL */
2624 Session::get_source (ARDOUR::id_t id)
2626 LockMonitor lm (source_lock, __LINE__, __FILE__);
2627 SourceList::iterator i;
2630 if ((i = sources.find (id)) != sources.end()) {
2631 source = (*i).second;
2638 Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
2642 char buf[PATH_MAX+1];
2643 const uint32_t limit = 10000;
2647 legalized = legalize_for_path (ds.name());
2649 /* find a "version" of the file name that doesn't exist in
2650 any of the possible directories.
2653 for (cnt = 1; cnt <= limit; ++cnt) {
2655 vector<space_and_path>::iterator i;
2656 uint32_t existing = 0;
2658 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2661 spath += sound_dir_name;
2665 if (ds.n_channels() < 2) {
2666 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2667 } else if (ds.n_channels() == 2) {
2669 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2671 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2673 } else if (ds.n_channels() < 26) {
2674 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2676 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2679 if (access (buf, F_OK) == 0) {
2684 if (existing == 0) {
2690 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, ds.name()) << endmsg;
2691 throw failed_constructor();
2694 /* we now have a unique name for the file, but figure out where to
2700 spath = discover_best_sound_dir ();
2702 string::size_type pos = foo.find_last_of ('/');
2704 if (pos == string::npos) {
2707 spath += foo.substr (pos + 1);
2710 /* this might throw failed_constructor(), which is OK */
2713 return new DestructiveFileSource (spath, frame_rate());
2715 return new FileSource (spath, frame_rate());
2719 /* Playlist management */
2722 Session::get_playlist (string name)
2726 if ((ret = playlist_by_name (name)) == 0) {
2727 ret = new AudioPlaylist (*this, name);
2734 Session::playlist_by_name (string name)
2736 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2737 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2738 if ((*i)->name() == name) {
2742 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2743 if ((*i)->name() == name) {
2751 Session::add_playlist (Playlist* playlist)
2753 if (playlist->hidden()) {
2758 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2759 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2760 playlists.insert (playlists.begin(), playlist);
2762 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2763 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2769 PlaylistAdded (playlist); /* EMIT SIGNAL */
2773 Session::track_playlist (Playlist* pl, bool inuse)
2775 PlaylistList::iterator x;
2778 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2781 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2783 unused_playlists.insert (pl);
2785 if ((x = playlists.find (pl)) != playlists.end()) {
2786 playlists.erase (x);
2791 //cerr << "shifting playlist to used: " << pl->name() << endl;
2793 playlists.insert (pl);
2795 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2796 unused_playlists.erase (x);
2803 Session::remove_playlist (Playlist* playlist)
2805 if (_state_of_the_state & Deletion) {
2810 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
2811 // cerr << "removing playlist: " << playlist->name() << endl;
2813 PlaylistList::iterator i;
2815 i = find (playlists.begin(), playlists.end(), playlist);
2817 if (i != playlists.end()) {
2818 playlists.erase (i);
2821 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
2822 if (i != unused_playlists.end()) {
2823 unused_playlists.erase (i);
2830 PlaylistRemoved (playlist); /* EMIT SIGNAL */
2834 Session::set_audition (AudioRegion* r)
2836 pending_audition_region = r;
2837 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
2838 schedule_butler_transport_work ();
2842 Session::non_realtime_set_audition ()
2844 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
2845 auditioner->audition_current_playlist ();
2846 } else if (pending_audition_region) {
2847 auditioner->audition_region (*pending_audition_region);
2849 pending_audition_region = 0;
2850 AuditionActive (true); /* EMIT SIGNAL */
2854 Session::audition_playlist ()
2856 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
2857 ev->set_ptr ((void*) 0xfeedface);
2862 Session::audition_region (AudioRegion& r)
2864 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
2870 Session::cancel_audition ()
2872 if (auditioner->active()) {
2873 auditioner->cancel_audition ();
2874 AuditionActive (false); /* EMIT SIGNAL */
2879 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
2881 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
2885 Session::remove_empty_sounds ()
2888 PathScanner scanner;
2893 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
2895 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
2897 if (FileSource::is_empty (*(*i))) {
2899 unlink ((*i)->c_str());
2901 string peak_path = peak_path_from_audio_path (**i);
2902 unlink (peak_path.c_str());
2908 delete possible_audiofiles;
2912 Session::is_auditioning () const
2914 /* can be called before we have an auditioner object */
2916 return auditioner->active();
2924 Session::peak_path_from_audio_path (string audio_path)
2926 /* XXX hardly bombproof! fix me */
2930 res = PBD::dirname (audio_path);
2931 res = PBD::dirname (res);
2933 res += peak_dir_name;
2935 res += PBD::basename_nosuffix (audio_path);
2942 Session::old_peak_path_from_audio_path (string audio_path)
2944 /* This is a hangover from when audio and peak files
2945 lived in the same directory. We need it to to
2946 be able to open old sessions.
2949 /* XXX hardly bombproof! fix me */
2951 string res = audio_path.substr (0, audio_path.find_last_of ('.'));
2957 Session::set_all_solo (bool yn)
2960 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2962 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2963 if (!(*i)->hidden()) {
2964 (*i)->set_solo (yn, this);
2973 Session::set_all_mute (bool yn)
2976 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2978 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2979 if (!(*i)->hidden()) {
2980 (*i)->set_mute (yn, this);
2989 Session::n_diskstreams () const
2991 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
2994 for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2995 if (!(*i)->hidden()) {
3003 Session::foreach_diskstream (void (DiskStream::*func)(void))
3005 RWLockMonitor lm (diskstream_lock, false, __LINE__, __FILE__);
3006 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3007 if (!(*i)->hidden()) {
3014 Session::graph_reordered ()
3016 /* don't do this stuff if we are setting up connections
3017 from a set_state() call.
3020 if (_state_of_the_state & InitialConnecting) {
3024 RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3025 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3029 /* force all diskstreams to update their capture offset values to
3030 reflect any changes in latencies within the graph.
3033 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3034 (*i)->set_capture_offset ();
3039 Session::record_disenable_all ()
3041 record_enable_change_all (false);
3045 Session::record_enable_all ()
3047 record_enable_change_all (true);
3051 Session::record_enable_change_all (bool yn)
3053 RWLockMonitor lm1 (route_lock, false, __LINE__, __FILE__);
3055 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3058 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3059 at->set_record_enable (yn, this);
3063 /* since we don't keep rec-enable state, don't mark session dirty */
3067 Session::add_redirect (Redirect* redirect)
3071 PortInsert* port_insert;
3072 PluginInsert* plugin_insert;
3074 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3075 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3076 _port_inserts.insert (_port_inserts.begin(), port_insert);
3077 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3078 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3080 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3083 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3084 _sends.insert (_sends.begin(), send);
3086 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3090 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3096 Session::remove_redirect (Redirect* redirect)
3100 PortInsert* port_insert;
3101 PluginInsert* plugin_insert;
3103 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3104 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3105 _port_inserts.remove (port_insert);
3106 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3107 _plugin_inserts.remove (plugin_insert);
3109 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3112 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3113 _sends.remove (send);
3115 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3123 Session::available_capture_duration ()
3125 const double scale = 4096.0 / sizeof (Sample);
3127 if (_total_free_4k_blocks * scale > (double) max_frames) {
3131 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3135 Session::add_connection (ARDOUR::Connection* connection)
3138 LockMonitor (connection_lock, __LINE__, __FILE__);
3139 _connections.push_back (connection);
3142 ConnectionAdded (connection); /* EMIT SIGNAL */
3148 Session::remove_connection (ARDOUR::Connection* connection)
3150 bool removed = false;
3153 LockMonitor (connection_lock, __LINE__, __FILE__);
3154 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3156 if (i != _connections.end()) {
3157 _connections.erase (i);
3163 ConnectionRemoved (connection); /* EMIT SIGNAL */
3169 ARDOUR::Connection *
3170 Session::connection_by_name (string name) const
3172 LockMonitor lm (connection_lock, __LINE__, __FILE__);
3174 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3175 if ((*i)->name() == name) {
3184 Session::set_edit_mode (EditMode mode)
3189 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3191 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3192 (*i)->set_edit_mode (mode);
3197 ControlChanged (EditingMode); /* EMIT SIGNAL */
3201 Session::tempo_map_changed (Change ignored)
3208 Session::ensure_passthru_buffers (uint32_t howmany)
3210 while (howmany > _passthru_buffers.size()) {
3212 #ifdef NO_POSIX_MEMALIGN
3213 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3215 posix_memalign((void **)&p,16,current_block_size * 4);
3217 _passthru_buffers.push_back (p);
3221 #ifdef NO_POSIX_MEMALIGN
3222 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3224 posix_memalign((void **)&p,16,current_block_size * 4);
3226 memset (p, 0, sizeof (Sample) * current_block_size);
3227 _silent_buffers.push_back (p);
3230 allocate_pan_automation_buffers (current_block_size, howmany, false);
3234 Session::next_send_name ()
3237 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3242 Session::next_insert_name ()
3245 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3249 /* Named Selection management */
3252 Session::named_selection_by_name (string name)
3254 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3255 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3256 if ((*i)->name == name) {
3264 Session::add_named_selection (NamedSelection* named_selection)
3267 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3268 named_selections.insert (named_selections.begin(), named_selection);
3273 NamedSelectionAdded (); /* EMIT SIGNAL */
3277 Session::remove_named_selection (NamedSelection* named_selection)
3279 bool removed = false;
3282 LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
3284 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3286 if (i != named_selections.end()) {
3288 named_selections.erase (i);
3295 NamedSelectionRemoved (); /* EMIT SIGNAL */
3300 Session::reset_native_file_format ()
3302 // jlc - WHY take routelock?
3303 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3304 RWLockMonitor lm2 (diskstream_lock, false, __LINE__, __FILE__);
3306 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3307 (*i)->reset_write_sources (false);
3312 Session::route_name_unique (string n) const
3314 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3316 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3317 if ((*i)->name() == n) {
3326 Session::remove_file_source (FileSource& fs)
3328 return fs.move_to_trash (dead_sound_dir_name);
3332 Session::n_playlists () const
3334 LockMonitor lm (playlist_lock, __LINE__, __FILE__);
3335 return playlists.size();
3339 Session::set_solo_model (SoloModel sm)
3341 if (sm != _solo_model) {
3343 ControlChanged (SoloingModel);
3349 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3351 if (!force && howmany <= _npan_buffers) {
3355 if (_pan_automation_buffer) {
3357 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3358 delete [] _pan_automation_buffer[i];
3361 delete [] _pan_automation_buffer;
3364 _pan_automation_buffer = new pan_t*[howmany];
3366 for (uint32_t i = 0; i < howmany; ++i) {
3367 _pan_automation_buffer[i] = new pan_t[nframes];
3370 _npan_buffers = howmany;
3374 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3376 Stateful::add_instant_xml (node, dir);
3377 Config->add_instant_xml (node, Config->get_user_ardour_path());
3381 Session::freeze (InterThreadInfo& itt)
3383 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3385 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3389 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3390 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3401 Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len, bool overwrite, vector<Source*>& srcs,
3402 InterThreadInfo& itt)
3406 FileSource* fsource;
3408 char buf[PATH_MAX+1];
3411 jack_nframes_t position;
3412 jack_nframes_t this_chunk;
3413 jack_nframes_t to_do;
3414 vector<Sample*> buffers;
3416 const jack_nframes_t chunk_size = (256 * 1024)/4;
3418 atomic_set (&processing_prohibited, 1);
3420 /* call tree *MUST* hold route_lock */
3422 if ((playlist = track.disk_stream().playlist()) == 0) {
3426 /* external redirects will be a problem */
3428 if (track.has_external_redirects()) {
3432 nchans = track.disk_stream().n_channels();
3434 dir = discover_best_sound_dir ();
3436 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3438 for (x = 0; x < 99999; ++x) {
3439 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3440 if (access (buf, F_OK) != 0) {
3446 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3451 fsource = new FileSource (buf, frame_rate());
3454 catch (failed_constructor& err) {
3455 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3459 srcs.push_back(fsource);
3462 /* XXX need to flush all redirects */
3467 /* create a set of reasonably-sized buffers */
3469 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3471 #ifdef NO_POSIX_MEMALIGN
3472 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3474 posix_memalign((void **)&b,16,chunk_size * 4);
3476 buffers.push_back (b);
3479 workbuf = new char[chunk_size * 4];
3481 while (to_do && !itt.cancel) {
3483 this_chunk = min (to_do, chunk_size);
3485 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3490 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3491 if ((*src)->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3496 start += this_chunk;
3497 to_do -= this_chunk;
3499 itt.progress = (float) (1.0 - ((double) to_do / len));
3508 xnow = localtime (&now);
3510 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3511 dynamic_cast<FileSource*>((*src))->update_header (position, *xnow, now);
3514 /* build peakfile for new source */
3516 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3517 dynamic_cast<FileSource*>(*src)->build_peaks ();
3525 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3526 dynamic_cast<FileSource*>(*src)->mark_for_remove ();
3531 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3539 atomic_set (&processing_prohibited, 0);
3547 Session::get_silent_buffers (uint32_t howmany)
3549 for (uint32_t i = 0; i < howmany; ++i) {
3550 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3552 return _silent_buffers;
3556 Session::ntracks () 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)) {
3571 Session::nbusses () const
3574 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
3576 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3577 if (dynamic_cast<AudioTrack*> (*i) == 0) {
3586 Session::set_layer_model (LayerModel lm)
3588 if (lm != layer_model) {
3591 ControlChanged (LayeringModel);
3596 Session::set_xfade_model (CrossfadeModel xm)
3598 if (xm != xfade_model) {
3601 ControlChanged (CrossfadingModel);