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>
37 #include <pbd/error.h>
38 #include <glibmm/thread.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/stl_delete.h>
41 #include <pbd/basename.h>
43 #include <ardour/audioengine.h>
44 #include <ardour/configuration.h>
45 #include <ardour/session.h>
46 #include <ardour/diskstream.h>
47 #include <ardour/utils.h>
48 #include <ardour/audioplaylist.h>
49 #include <ardour/audioregion.h>
50 #include <ardour/source.h>
51 #include <ardour/filesource.h>
52 #include <ardour/destructive_filesource.h>
53 #include <ardour/sndfilesource.h>
54 #include <ardour/auditioner.h>
55 #include <ardour/recent_sessions.h>
56 #include <ardour/redirect.h>
57 #include <ardour/send.h>
58 #include <ardour/insert.h>
59 #include <ardour/connection.h>
60 #include <ardour/slave.h>
61 #include <ardour/tempo.h>
62 #include <ardour/audio_track.h>
63 #include <ardour/cycle_timer.h>
64 #include <ardour/named_selection.h>
65 #include <ardour/crossfade.h>
66 #include <ardour/playlist.h>
67 #include <ardour/click.h>
70 #include <ardour/osc.h>
76 using namespace ARDOUR;
77 //using namespace sigc;
79 const char* Session::_template_suffix = X_(".template");
80 const char* Session::_statefile_suffix = X_(".ardour");
81 const char* Session::_pending_suffix = X_(".pending");
82 const char* Session::sound_dir_name = X_("sounds");
83 const char* Session::tape_dir_name = X_("tapes");
84 const char* Session::peak_dir_name = X_("peaks");
85 const char* Session::dead_sound_dir_name = X_("dead_sounds");
87 Session::compute_peak_t Session::compute_peak = 0;
88 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
89 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
90 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
92 sigc::signal<int> Session::AskAboutPendingState;
95 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
102 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
103 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
109 /* check to see if it exists, and what it is */
111 if (stat (str.c_str(), &statbuf)) {
112 if (errno == ENOENT) {
115 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
123 /* it exists, so it must either be the name
124 of the directory, or the name of the statefile
128 if (S_ISDIR (statbuf.st_mode)) {
130 string::size_type slash = str.find_last_of ('/');
132 if (slash == string::npos) {
134 /* a subdirectory of cwd, so statefile should be ... */
140 tmp += _statefile_suffix;
144 if (stat (tmp.c_str(), &statbuf)) {
145 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
155 /* some directory someplace in the filesystem.
156 the snapshot name is the directory name
161 snapshot = str.substr (slash+1);
165 } else if (S_ISREG (statbuf.st_mode)) {
167 string::size_type slash = str.find_last_of ('/');
168 string::size_type suffix;
170 /* remove the suffix */
172 if (slash != string::npos) {
173 snapshot = str.substr (slash+1);
178 suffix = snapshot.find (_statefile_suffix);
180 if (suffix == string::npos) {
181 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
187 snapshot = snapshot.substr (0, suffix);
189 if (slash == string::npos) {
191 /* we must be in the directory where the
192 statefile lives. get it using cwd().
195 char cwd[PATH_MAX+1];
197 if (getcwd (cwd, sizeof (cwd)) == 0) {
198 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
207 /* full path to the statefile */
209 path = str.substr (0, slash);
214 /* what type of file is it? */
215 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
221 /* its the name of a new directory. get the name
225 string::size_type slash = str.find_last_of ('/');
227 if (slash == string::npos) {
229 /* no slash, just use the name, but clean it up */
231 path = legalize_for_path (str);
237 snapshot = str.substr (slash+1);
244 Session::Session (AudioEngine &eng,
246 string snapshot_name,
247 string* mix_template)
250 _mmc_port (default_mmc_port),
251 _mtc_port (default_mtc_port),
252 _midi_port (default_midi_port),
253 pending_events (2048),
254 midi_requests (128), // the size of this should match the midi request pool size
259 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
261 n_physical_outputs = _engine.n_physical_outputs();
262 n_physical_inputs = _engine.n_physical_inputs();
264 first_stage_init (fullpath, snapshot_name);
266 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
267 throw failed_constructor ();
270 if (second_stage_init (new_session)) {
271 throw failed_constructor ();
274 store_recent_sessions(_name, _path);
276 bool was_dirty = dirty();
278 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
281 DirtyChanged (); /* EMIT SIGNAL */
285 Session::Session (AudioEngine &eng,
287 string snapshot_name,
288 AutoConnectOption input_ac,
289 AutoConnectOption output_ac,
290 uint32_t control_out_channels,
291 uint32_t master_out_channels,
292 uint32_t requested_physical_in,
293 uint32_t requested_physical_out,
294 jack_nframes_t initial_length)
297 _mmc_port (default_mmc_port),
298 _mtc_port (default_mtc_port),
299 _midi_port (default_midi_port),
300 pending_events (2048),
307 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
309 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
310 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
312 first_stage_init (fullpath, snapshot_name);
314 if (create (new_session, 0, initial_length)) {
315 throw failed_constructor ();
318 if (control_out_channels) {
320 r = new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut);
325 if (master_out_channels) {
327 r = new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut);
331 /* prohibit auto-connect to master, because there isn't one */
332 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
335 input_auto_connect = input_ac;
336 output_auto_connect = output_ac;
338 if (second_stage_init (new_session)) {
339 throw failed_constructor ();
342 store_recent_sessions(_name, _path);
344 bool was_dirty = dirty ();
346 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
349 DirtyChanged (); /* EMIT SIGNAL */
355 /* if we got to here, leaving pending capture state around
359 remove_pending_capture_state ();
361 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
362 _engine.remove_session ();
364 going_away (); /* EMIT SIGNAL */
366 terminate_butler_thread ();
367 terminate_midi_thread ();
369 if (click_data && click_data != default_click) {
370 delete [] click_data;
373 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
374 delete [] click_emphasis_data;
388 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
392 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
396 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
400 for (map<RunContext,char*>::iterator i = _conversion_buffers.begin(); i != _conversion_buffers.end(); ++i) {
401 delete [] (i->second);
404 #undef TRACK_DESTRUCTION
405 #ifdef TRACK_DESTRUCTION
406 cerr << "delete named selections\n";
407 #endif /* TRACK_DESTRUCTION */
408 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
409 NamedSelectionList::iterator tmp;
418 #ifdef TRACK_DESTRUCTION
419 cerr << "delete playlists\n";
420 #endif /* TRACK_DESTRUCTION */
421 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
422 PlaylistList::iterator tmp;
432 #ifdef TRACK_DESTRUCTION
433 cerr << "delete audio regions\n";
434 #endif /* TRACK_DESTRUCTION */
435 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
436 AudioRegionList::iterator tmp;
446 #ifdef TRACK_DESTRUCTION
447 cerr << "delete routes\n";
448 #endif /* TRACK_DESTRUCTION */
449 for (RouteList::iterator i = routes.begin(); i != routes.end(); ) {
450 RouteList::iterator tmp;
457 #ifdef TRACK_DESTRUCTION
458 cerr << "delete diskstreams\n";
459 #endif /* TRACK_DESTRUCTION */
460 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
461 DiskStreamList::iterator tmp;
471 #ifdef TRACK_DESTRUCTION
472 cerr << "delete sources\n";
473 #endif /* TRACK_DESTRUCTION */
474 for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
475 SourceList::iterator tmp;
485 #ifdef TRACK_DESTRUCTION
486 cerr << "delete mix groups\n";
487 #endif /* TRACK_DESTRUCTION */
488 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
489 list<RouteGroup*>::iterator tmp;
499 #ifdef TRACK_DESTRUCTION
500 cerr << "delete edit groups\n";
501 #endif /* TRACK_DESTRUCTION */
502 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
503 list<RouteGroup*>::iterator tmp;
513 #ifdef TRACK_DESTRUCTION
514 cerr << "delete connections\n";
515 #endif /* TRACK_DESTRUCTION */
516 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
517 ConnectionList::iterator tmp;
527 if (butler_mixdown_buffer) {
528 delete [] butler_mixdown_buffer;
531 if (butler_gain_buffer) {
532 delete [] butler_gain_buffer;
535 Crossfade::set_buffer_size (0);
547 Session::set_worst_io_latencies (bool take_lock)
549 _worst_output_latency = 0;
550 _worst_input_latency = 0;
552 if (!_engine.connected()) {
557 route_lock.reader_lock ();
560 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
561 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
562 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
566 route_lock.reader_unlock ();
571 Session::when_engine_running ()
573 string first_physical_output;
575 /* we don't want to run execute this again */
577 first_time_running.disconnect ();
579 set_block_size (_engine.frames_per_cycle());
580 set_frame_rate (_engine.frame_rate());
582 /* every time we reconnect, recompute worst case output latencies */
584 _engine.Running.connect (sigc::bind (mem_fun (*this, &Session::set_worst_io_latencies), true));
586 if (synced_to_jack()) {
587 _engine.transport_stop ();
590 if (Config->get_jack_time_master()) {
591 _engine.transport_locate (_transport_frame);
599 _click_io = new ClickIO (*this, "click", 0, 0, -1, -1);
601 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
603 /* existing state for Click */
605 if (_click_io->set_state (*child->children().front()) == 0) {
607 _clicking = click_requested;
611 error << _("could not setup Click I/O") << endmsg;
617 /* default state for Click */
619 first_physical_output = _engine.get_nth_physical_output (0);
621 if (first_physical_output.length()) {
622 if (_click_io->add_output_port (first_physical_output, this)) {
623 // relax, even though its an error
625 _clicking = click_requested;
631 catch (failed_constructor& err) {
632 error << _("cannot setup Click I/O") << endmsg;
635 set_worst_io_latencies (true);
638 ControlChanged (Clicking); /* EMIT SIGNAL */
641 if (auditioner == 0) {
643 /* we delay creating the auditioner till now because
644 it makes its own connections to ports named
645 in the ARDOUR_RC config file. the engine has
646 to be running for this to work.
650 auditioner = new Auditioner (*this);
653 catch (failed_constructor& err) {
654 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
658 /* Create a set of Connection objects that map
659 to the physical outputs currently available
664 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
666 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
668 Connection* c = new OutputConnection (buf, true);
671 c->add_connection (0, _engine.get_nth_physical_output (np));
676 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
678 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
680 Connection* c = new InputConnection (buf, true);
683 c->add_connection (0, _engine.get_nth_physical_input (np));
690 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
692 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
694 Connection* c = new OutputConnection (buf, true);
698 c->add_connection (0, _engine.get_nth_physical_output (np));
699 c->add_connection (1, _engine.get_nth_physical_output (np+1));
704 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
706 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
708 Connection* c = new InputConnection (buf, true);
712 c->add_connection (0, _engine.get_nth_physical_input (np));
713 c->add_connection (1, _engine.get_nth_physical_input (np+1));
722 /* create master/control ports */
727 /* force the master to ignore any later call to this */
729 if (_master_out->pending_state_node) {
730 _master_out->ports_became_legal();
733 /* no panner resets till we are through */
735 _master_out->defer_pan_reset ();
737 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
738 if (_master_out->add_input_port ("", this)) {
739 error << _("cannot setup master inputs")
745 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
746 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
747 error << _("cannot setup master outputs")
754 _master_out->allow_pan_reset ();
758 Connection* c = new OutputConnection (_("Master Out"), true);
760 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
762 c->add_connection ((int) n, _master_out->input(n)->name());
769 /* catch up on send+insert cnts */
773 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
776 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
777 if (id > insert_cnt) {
785 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
788 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
795 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
797 /* hook us up to the engine */
799 _engine.set_session (this);
804 osc->set_session (*this);
807 _state_of_the_state = Clean;
809 DirtyChanged (); /* EMIT SIGNAL */
813 Session::hookup_io ()
815 /* stop graph reordering notifications from
816 causing resorts, etc.
819 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
821 /* Tell all IO objects to create their ports */
828 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
829 if (_control_out->add_input_port ("", this)) {
830 error << _("cannot setup control inputs")
836 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
837 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
838 error << _("cannot set up master outputs")
846 /* Tell all IO objects to connect themselves together */
848 IO::enable_connecting ();
850 /* Now reset all panners */
852 IO::reset_panners ();
854 /* Anyone who cares about input state, wake up and do something */
856 IOConnectionsComplete (); /* EMIT SIGNAL */
858 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
860 /* now handle the whole enchilada as if it was one
866 /* update mixer solo state */
872 Session::playlist_length_changed (Playlist* pl)
874 /* we can't just increase end_location->end() if pl->get_maximum_extent()
875 if larger. if the playlist used to be the longest playlist,
876 and its now shorter, we have to decrease end_location->end(). hence,
877 we have to iterate over all diskstreams and check the
878 playlists currently in use.
884 Session::diskstream_playlist_changed (DiskStream* dstream)
888 if ((playlist = dstream->playlist()) != 0) {
889 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
892 /* see comment in playlist_length_changed () */
897 Session::record_enabling_legal () const
899 /* this used to be in here, but survey says.... we don't need to restrict it */
900 // if (record_status() == Recording) {
911 Session::set_auto_play (bool yn)
913 if (auto_play != yn) {
916 ControlChanged (AutoPlay);
921 Session::set_auto_return (bool yn)
923 if (auto_return != yn) {
926 ControlChanged (AutoReturn);
931 Session::set_crossfades_active (bool yn)
933 if (crossfades_active != yn) {
934 crossfades_active = yn;
936 ControlChanged (CrossFadesActive);
941 Session::set_do_not_record_plugins (bool yn)
943 if (do_not_record_plugins != yn) {
944 do_not_record_plugins = yn;
946 ControlChanged (RecordingPlugins);
951 Session::set_auto_input (bool yn)
953 if (auto_input != yn) {
956 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
957 /* auto-input only makes a difference if we're rolling */
959 /* Even though this can called from RT context we are using
960 a non-tentative rwlock here, because the action must occur.
961 The rarity and short potential lock duration makes this "OK"
963 Glib::RWLock::ReaderLock dsm (diskstream_lock);
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 (!auto_input);
973 ControlChanged (AutoInput);
978 Session::reset_input_monitor_state ()
980 if (transport_rolling()) {
981 Glib::RWLock::ReaderLock dsm (diskstream_lock);
982 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
983 if ((*i)->record_enabled ()) {
984 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
985 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
989 Glib::RWLock::ReaderLock dsm (diskstream_lock);
990 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
991 if ((*i)->record_enabled ()) {
992 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
993 (*i)->monitor_input (Config->get_use_hardware_monitoring());
1001 Session::set_input_auto_connect (bool yn)
1004 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
1006 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1012 Session::get_input_auto_connect () const
1014 return (input_auto_connect & AutoConnectPhysical);
1018 Session::set_output_auto_connect (AutoConnectOption aco)
1020 output_auto_connect = aco;
1025 Session::auto_punch_start_changed (Location* location)
1027 replace_event (Event::PunchIn, location->start());
1029 if (get_record_enabled() && get_punch_in()) {
1030 /* capture start has been changed, so save new pending state */
1031 save_state ("", true);
1036 Session::auto_punch_end_changed (Location* location)
1038 jack_nframes_t when_to_stop = location->end();
1039 // when_to_stop += _worst_output_latency + _worst_input_latency;
1040 replace_event (Event::PunchOut, when_to_stop);
1044 Session::auto_punch_changed (Location* location)
1046 jack_nframes_t when_to_stop = location->end();
1048 replace_event (Event::PunchIn, location->start());
1049 //when_to_stop += _worst_output_latency + _worst_input_latency;
1050 replace_event (Event::PunchOut, when_to_stop);
1054 Session::auto_loop_changed (Location* location)
1056 replace_event (Event::AutoLoop, location->end(), location->start());
1058 if (transport_rolling() && get_auto_loop()) {
1060 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1062 if (_transport_frame > location->end()) {
1063 // relocate to beginning of loop
1064 clear_events (Event::LocateRoll);
1066 request_locate (location->start(), true);
1069 else if (seamless_loop && !loop_changing) {
1071 // schedule a locate-roll to refill the diskstreams at the
1072 // previous loop end
1073 loop_changing = true;
1075 if (location->end() > last_loopend) {
1076 clear_events (Event::LocateRoll);
1077 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1084 last_loopend = location->end();
1089 Session::set_auto_punch_location (Location* location)
1093 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1094 auto_punch_start_changed_connection.disconnect();
1095 auto_punch_end_changed_connection.disconnect();
1096 auto_punch_changed_connection.disconnect();
1097 existing->set_auto_punch (false, this);
1098 remove_event (existing->start(), Event::PunchIn);
1099 clear_events (Event::PunchOut);
1100 auto_punch_location_changed (0);
1105 if (location == 0) {
1109 if (location->end() <= location->start()) {
1110 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1114 auto_punch_start_changed_connection.disconnect();
1115 auto_punch_end_changed_connection.disconnect();
1116 auto_punch_changed_connection.disconnect();
1118 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1119 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1120 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1122 location->set_auto_punch (true, this);
1123 auto_punch_location_changed (location);
1127 Session::set_punch_in (bool yn)
1129 if (punch_in == yn) {
1135 if ((location = _locations.auto_punch_location()) != 0) {
1136 if ((punch_in = yn) == true) {
1137 replace_event (Event::PunchIn, location->start());
1139 remove_event (location->start(), Event::PunchIn);
1144 ControlChanged (PunchIn); /* EMIT SIGNAL */
1148 Session::set_punch_out (bool yn)
1150 if (punch_out == yn) {
1156 if ((location = _locations.auto_punch_location()) != 0) {
1157 if ((punch_out = yn) == true) {
1158 replace_event (Event::PunchOut, location->end());
1160 clear_events (Event::PunchOut);
1165 ControlChanged (PunchOut); /* EMIT SIGNAL */
1169 Session::set_auto_loop_location (Location* location)
1173 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1174 auto_loop_start_changed_connection.disconnect();
1175 auto_loop_end_changed_connection.disconnect();
1176 auto_loop_changed_connection.disconnect();
1177 existing->set_auto_loop (false, this);
1178 remove_event (existing->end(), Event::AutoLoop);
1179 auto_loop_location_changed (0);
1184 if (location == 0) {
1188 if (location->end() <= location->start()) {
1189 error << _("Session: you can't use a mark for auto loop") << endmsg;
1193 last_loopend = location->end();
1195 auto_loop_start_changed_connection.disconnect();
1196 auto_loop_end_changed_connection.disconnect();
1197 auto_loop_changed_connection.disconnect();
1199 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1200 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1201 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1203 location->set_auto_loop (true, this);
1204 auto_loop_location_changed (location);
1208 Session::locations_added (Location* ignored)
1214 Session::locations_changed ()
1216 _locations.apply (*this, &Session::handle_locations_changed);
1220 Session::handle_locations_changed (Locations::LocationList& locations)
1222 Locations::LocationList::iterator i;
1224 bool set_loop = false;
1225 bool set_punch = false;
1227 for (i = locations.begin(); i != locations.end(); ++i) {
1231 if (location->is_auto_punch()) {
1232 set_auto_punch_location (location);
1235 if (location->is_auto_loop()) {
1236 set_auto_loop_location (location);
1243 set_auto_loop_location (0);
1246 set_auto_punch_location (0);
1253 Session::enable_record ()
1255 /* XXX really atomic compare+swap here */
1256 if (g_atomic_int_get (&_record_status) != Recording) {
1257 g_atomic_int_set (&_record_status, Recording);
1258 _last_record_location = _transport_frame;
1259 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1261 if (Config->get_use_hardware_monitoring() && auto_input) {
1262 /* Even though this can be called from RT context we are using
1263 a non-tentative rwlock here, because the action must occur.
1264 The rarity and short potential lock duration makes this "OK"
1266 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1268 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1269 if ((*i)->record_enabled ()) {
1270 (*i)->monitor_input (true);
1275 RecordStateChanged ();
1280 Session::disable_record (bool rt_context, bool force)
1284 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1286 if (!Config->get_latched_record_enable () || force) {
1287 g_atomic_int_set (&_record_status, Disabled);
1289 if (rs == Recording) {
1290 g_atomic_int_set (&_record_status, Enabled);
1294 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1296 if (Config->get_use_hardware_monitoring() && auto_input) {
1297 /* Even though this can be called from RT context we are using
1298 a non-tentative rwlock here, because the action must occur.
1299 The rarity and short potential lock duration makes this "OK"
1301 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1303 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1304 if ((*i)->record_enabled ()) {
1305 (*i)->monitor_input (false);
1310 RecordStateChanged (); /* emit signal */
1313 remove_pending_capture_state ();
1319 Session::step_back_from_record ()
1321 g_atomic_int_set (&_record_status, Enabled);
1323 if (Config->get_use_hardware_monitoring()) {
1324 /* Even though this can be called from RT context we are using
1325 a non-tentative rwlock here, because the action must occur.
1326 The rarity and short potential lock duration makes this "OK"
1328 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1330 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1331 if (auto_input && (*i)->record_enabled ()) {
1332 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1333 (*i)->monitor_input (false);
1340 Session::maybe_enable_record ()
1342 g_atomic_int_set (&_record_status, Enabled);
1344 /* XXX this save should really happen in another thread. its needed so that
1345 pending capture state can be recovered if we crash.
1348 save_state ("", true);
1350 if (_transport_speed) {
1355 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1356 RecordStateChanged (); /* EMIT SIGNAL */
1363 Session::audible_frame () const
1366 jack_nframes_t offset;
1369 /* the first of these two possible settings for "offset"
1370 mean that the audible frame is stationary until
1371 audio emerges from the latency compensation
1374 the second means that the audible frame is stationary
1375 until audio would emerge from a physical port
1376 in the absence of any plugin latency compensation
1379 offset = _worst_output_latency;
1381 if (offset > current_block_size) {
1382 offset -= current_block_size;
1384 /* XXX is this correct? if we have no external
1385 physical connections and everything is internal
1386 then surely this is zero? still, how
1387 likely is that anyway?
1389 offset = current_block_size;
1392 if (synced_to_jack()) {
1393 tf = _engine.transport_frame();
1395 tf = _transport_frame;
1398 if (_transport_speed == 0) {
1408 if (!non_realtime_work_pending()) {
1412 /* take latency into account */
1421 Session::set_frame_rate (jack_nframes_t frames_per_second)
1423 /** \fn void Session::set_frame_size(jack_nframes_t)
1424 the AudioEngine object that calls this guarantees
1425 that it will not be called while we are also in
1426 ::process(). Its fine to do things that block
1430 _current_frame_rate = frames_per_second;
1431 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1433 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1437 /* XXX need to reset/reinstantiate all LADSPA plugins */
1441 Session::set_block_size (jack_nframes_t nframes)
1443 /* the AudioEngine guarantees
1444 that it will not be called while we are also in
1445 ::process(). It is therefore fine to do things that block
1450 Glib::RWLock::ReaderLock lm (route_lock);
1451 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1452 vector<Sample*>::iterator i;
1455 current_block_size = nframes;
1457 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1461 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1465 _passthru_buffers.clear ();
1466 _silent_buffers.clear ();
1468 ensure_passthru_buffers (np);
1470 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1474 #ifdef NO_POSIX_MEMALIGN
1475 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1477 posix_memalign((void **)&buf,16,current_block_size * 4);
1481 memset (*i, 0, sizeof (Sample) * current_block_size);
1485 if (_gain_automation_buffer) {
1486 delete [] _gain_automation_buffer;
1488 _gain_automation_buffer = new gain_t[nframes];
1490 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1492 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1493 (*i)->set_block_size (nframes);
1496 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1497 (*i)->set_block_size (nframes);
1500 set_worst_io_latencies (false);
1505 Session::set_default_fade (float steepness, float fade_msecs)
1508 jack_nframes_t fade_frames;
1510 /* Don't allow fade of less 1 frame */
1512 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1519 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1523 default_fade_msecs = fade_msecs;
1524 default_fade_steepness = steepness;
1527 // jlc, WTF is this!
1528 Glib::RWLock::ReaderLock lm (route_lock);
1529 AudioRegion::set_default_fade (steepness, fade_frames);
1534 /* XXX have to do this at some point */
1535 /* foreach region using default fade, reset, then
1536 refill_all_diskstream_buffers ();
1541 struct RouteSorter {
1542 bool operator() (Route* r1, Route* r2) {
1543 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1545 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1548 if (r1->fed_by.empty()) {
1549 if (r2->fed_by.empty()) {
1550 /* no ardour-based connections inbound to either route. just use signal order */
1551 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1553 /* r2 has connections, r1 does not; run r1 early */
1557 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1564 trace_terminal (Route* r1, Route* rbase)
1568 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1569 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1573 /* make a copy of the existing list of routes that feed r1 */
1575 set<Route *> existing = r1->fed_by;
1577 /* for each route that feeds r1, recurse, marking it as feeding
1581 for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
1584 /* r2 is a route that feeds r1 which somehow feeds base. mark
1585 base as being fed by r2
1588 rbase->fed_by.insert (r2);
1592 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1596 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1600 /* now recurse, so that we can mark base as being fed by
1601 all routes that feed r2
1604 trace_terminal (r2, rbase);
1611 Session::resort_routes (void* src)
1613 /* don't do anything here with signals emitted
1614 by Routes while we are being destroyed.
1617 if (_state_of_the_state & Deletion) {
1621 /* Caller MUST hold the route_lock */
1623 RouteList::iterator i, j;
1625 for (i = routes.begin(); i != routes.end(); ++i) {
1627 (*i)->fed_by.clear ();
1629 for (j = routes.begin(); j != routes.end(); ++j) {
1631 /* although routes can feed themselves, it will
1632 cause an endless recursive descent if we
1633 detect it. so don't bother checking for
1641 if ((*j)->feeds (*i)) {
1642 (*i)->fed_by.insert (*j);
1647 for (i = routes.begin(); i != routes.end(); ++i) {
1648 trace_terminal (*i, *i);
1655 cerr << "finished route resort\n";
1657 for (i = routes.begin(); i != routes.end(); ++i) {
1658 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1666 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1669 char track_name[32];
1671 uint32_t channels_used = 0;
1673 uint32_t nphysical_in;
1674 uint32_t nphysical_out;
1676 /* count existing audio tracks */
1679 Glib::RWLock::ReaderLock lm (route_lock);
1680 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1681 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1682 if (!(*i)->hidden()) {
1684 channels_used += (*i)->n_inputs();
1690 /* check for duplicate route names, since we might have pre-existing
1691 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1692 save, close,restart,add new route - first named route is now
1697 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1698 if (route_by_name (track_name) == 0) {
1703 } while (n < (UINT_MAX-1));
1705 if (input_auto_connect & AutoConnectPhysical) {
1706 nphysical_in = n_physical_inputs;
1711 if (output_auto_connect & AutoConnectPhysical) {
1712 nphysical_out = n_physical_outputs;
1718 track = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1720 if (track->ensure_io (input_channels, output_channels, false, this)) {
1721 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1722 input_channels, output_channels)
1727 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1731 if (input_auto_connect & AutoConnectPhysical) {
1732 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1735 if (port.length() && track->connect_input (track->input (x), port, this)) {
1741 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1745 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1746 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1747 } else if (output_auto_connect & AutoConnectMaster) {
1749 port = _master_out->input (x%_master_out->n_inputs())->name();
1753 if (port.length() && track->connect_output (track->output (x), port, this)) {
1759 vector<string> cports;
1760 uint32_t ni = _control_out->n_inputs();
1762 for (n = 0; n < ni; ++n) {
1763 cports.push_back (_control_out->input(n)->name());
1766 track->set_control_outs (cports);
1769 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1773 track->set_remote_control_id (ntracks());
1776 catch (failed_constructor &err) {
1777 error << _("Session: could not create new audio track.") << endmsg;
1785 Session::new_audio_route (int input_channels, int output_channels)
1792 /* count existing audio busses */
1795 Glib::RWLock::ReaderLock lm (route_lock);
1796 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1797 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1798 if (!(*i)->hidden()) {
1806 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1807 if (route_by_name (bus_name) == 0) {
1812 } while (n < (UINT_MAX-1));
1815 bus = new Route (*this, bus_name, -1, -1, -1, -1);
1817 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1818 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1819 input_channels, output_channels)
1823 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1827 if (input_auto_connect & AutoConnectPhysical) {
1828 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1831 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1836 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1840 if (output_auto_connect & AutoConnectPhysical) {
1841 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1842 } else if (output_auto_connect & AutoConnectMaster) {
1844 port = _master_out->input (x%_master_out->n_inputs())->name();
1848 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1854 vector<string> cports;
1855 uint32_t ni = _control_out->n_inputs();
1857 for (uint32_t n = 0; n < ni; ++n) {
1858 cports.push_back (_control_out->input(n)->name());
1860 bus->set_control_outs (cports);
1866 catch (failed_constructor &err) {
1867 error << _("Session: could not create new route.") << endmsg;
1875 Session::add_route (Route* route)
1878 Glib::RWLock::WriterLock lm (route_lock);
1879 routes.push_front (route);
1883 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1884 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1885 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1886 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1888 if (route->master()) {
1889 _master_out = route;
1892 if (route->control()) {
1893 _control_out = route;
1897 save_state (_current_snapshot_name);
1899 RouteAdded (route); /* EMIT SIGNAL */
1903 Session::add_diskstream (DiskStream* dstream)
1905 /* need to do this in case we're rolling at the time, to prevent false underruns */
1906 dstream->do_refill(0, 0, 0);
1909 Glib::RWLock::WriterLock lm (diskstream_lock);
1910 diskstreams.push_back (dstream);
1913 /* take a reference to the diskstream, preventing it from
1914 ever being deleted until the session itself goes away,
1915 or chooses to remove it for its own purposes.
1919 dstream->set_block_size (current_block_size);
1921 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1922 /* this will connect to future changes, and check the current length */
1923 diskstream_playlist_changed (dstream);
1925 dstream->prepare ();
1928 save_state (_current_snapshot_name);
1930 DiskStreamAdded (dstream); /* EMIT SIGNAL */
1934 Session::remove_route (Route& route)
1937 Glib::RWLock::WriterLock lm (route_lock);
1938 routes.remove (&route);
1940 /* deleting the master out seems like a dumb
1941 idea, but its more of a UI policy issue
1945 if (&route == _master_out) {
1949 if (&route == _control_out) {
1952 /* cancel control outs for all routes */
1954 vector<string> empty;
1956 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
1957 (*r)->set_control_outs (empty);
1961 update_route_solo_state ();
1965 Glib::RWLock::WriterLock lm (diskstream_lock);
1969 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
1970 diskstreams.remove (&at->disk_stream());
1971 at->disk_stream().unref ();
1974 find_current_end ();
1977 update_latency_compensation (false, false);
1980 /* XXX should we disconnect from the Route's signals ? */
1982 save_state (_current_snapshot_name);
1988 Session::route_mute_changed (void* src)
1994 Session::route_solo_changed (void* src, Route* route)
1996 if (solo_update_disabled) {
2001 Glib::RWLock::ReaderLock lm (route_lock);
2004 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
2006 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2008 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2012 /* don't mess with busses */
2014 if (dynamic_cast<AudioTrack*>(*i) == 0) {
2020 /* don't mess with tracks */
2022 if (dynamic_cast<AudioTrack*>(*i) != 0) {
2027 if ((*i) != route &&
2028 ((*i)->mix_group () == 0 ||
2029 (*i)->mix_group () != route->mix_group () ||
2030 !route->mix_group ()->is_active())) {
2032 if ((*i)->soloed()) {
2034 /* if its already soloed, and solo latching is enabled,
2035 then leave it as it is.
2038 if (_solo_latched) {
2045 solo_update_disabled = true;
2046 (*i)->set_solo (false, src);
2047 solo_update_disabled = false;
2051 bool something_soloed = false;
2052 bool same_thing_soloed = false;
2053 bool signal = false;
2055 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2056 if ((*i)->soloed()) {
2057 something_soloed = true;
2058 if (dynamic_cast<AudioTrack*>(*i)) {
2060 same_thing_soloed = true;
2065 same_thing_soloed = true;
2073 if (something_soloed != currently_soloing) {
2075 currently_soloing = something_soloed;
2078 modify_solo_mute (is_track, same_thing_soloed);
2081 SoloActive (currently_soloing);
2088 Session::set_solo_latched (bool yn)
2090 if (yn != _solo_latched) {
2093 ControlChanged (SoloLatch);
2098 Session::update_route_solo_state ()
2101 bool is_track = false;
2102 bool signal = false;
2104 /* caller must hold RouteLock */
2106 /* this is where we actually implement solo by changing
2107 the solo mute setting of each track.
2110 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2111 if ((*i)->soloed()) {
2113 if (dynamic_cast<AudioTrack*>(*i)) {
2120 if (mute != currently_soloing) {
2122 currently_soloing = mute;
2125 if (!is_track && !mute) {
2127 /* nothing is soloed */
2129 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2130 (*i)->set_solo_mute (false);
2140 modify_solo_mute (is_track, mute);
2143 SoloActive (currently_soloing);
2148 Session::modify_solo_mute (bool is_track, bool mute)
2150 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2154 /* only alter track solo mute */
2156 if (dynamic_cast<AudioTrack*>(*i)) {
2157 if ((*i)->soloed()) {
2158 (*i)->set_solo_mute (!mute);
2160 (*i)->set_solo_mute (mute);
2166 /* only alter bus solo mute */
2168 if (!dynamic_cast<AudioTrack*>(*i)) {
2170 if ((*i)->soloed()) {
2172 (*i)->set_solo_mute (false);
2176 /* don't mute master or control outs
2177 in response to another bus solo
2180 if ((*i) != _master_out &&
2181 (*i) != _control_out) {
2182 (*i)->set_solo_mute (mute);
2193 Session::catch_up_on_solo ()
2195 /* this is called after set_state() to catch the full solo
2196 state, which can't be correctly determined on a per-route
2197 basis, but needs the global overview that only the session
2200 Glib::RWLock::ReaderLock lm (route_lock);
2201 update_route_solo_state();
2205 Session::route_by_name (string name)
2207 Glib::RWLock::ReaderLock lm (route_lock);
2209 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2210 if ((*i)->name() == name) {
2219 Session::route_by_remote_id (uint32_t id)
2221 Glib::RWLock::ReaderLock lm (route_lock);
2223 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2224 if ((*i)->remote_control_id() == id) {
2233 Session::find_current_end ()
2235 if (_state_of_the_state & Loading) {
2239 jack_nframes_t max = get_maximum_extent ();
2241 if (max > end_location->end()) {
2242 end_location->set_end (max);
2244 DurationChanged(); /* EMIT SIGNAL */
2249 Session::get_maximum_extent () const
2251 jack_nframes_t max = 0;
2254 /* Don't take the diskstream lock. Caller must have other ways to
2258 for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2259 Playlist* pl = (*i)->playlist();
2260 if ((me = pl->get_maximum_extent()) > max) {
2269 Session::diskstream_by_name (string name)
2271 Glib::RWLock::ReaderLock lm (diskstream_lock);
2273 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2274 if ((*i)->name() == name) {
2283 Session::diskstream_by_id (id_t id)
2285 Glib::RWLock::ReaderLock lm (diskstream_lock);
2287 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2288 if ((*i)->id() == id) {
2296 /* AudioRegion management */
2299 Session::new_region_name (string old)
2301 string::size_type last_period;
2303 string::size_type len = old.length() + 64;
2306 if ((last_period = old.find_last_of ('.')) == string::npos) {
2308 /* no period present - add one explicitly */
2311 last_period = old.length() - 1;
2316 number = atoi (old.substr (last_period+1).c_str());
2320 while (number < (UINT_MAX-1)) {
2322 AudioRegionList::const_iterator i;
2327 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2330 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2331 if ((*i).second->name() == sbuf) {
2336 if (i == audio_regions.end()) {
2341 if (number != (UINT_MAX-1)) {
2345 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2350 Session::region_name (string& result, string base, bool newlevel) const
2357 Glib::Mutex::Lock lm (region_lock);
2359 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2367 /* XXX this is going to be slow. optimize me later */
2372 string::size_type pos;
2374 pos = base.find_last_of ('.');
2376 /* pos may be npos, but then we just use entire base */
2378 subbase = base.substr (0, pos);
2382 bool name_taken = true;
2385 Glib::Mutex::Lock lm (region_lock);
2387 for (int n = 1; n < 5000; ++n) {
2390 snprintf (buf, sizeof (buf), ".%d", n);
2395 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2396 if ((*i).second->name() == result) {
2409 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2417 Session::add_region (Region* region)
2419 AudioRegion* ar = 0;
2420 AudioRegion* oar = 0;
2424 Glib::Mutex::Lock lm (region_lock);
2426 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2428 AudioRegionList::iterator x;
2430 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2432 oar = dynamic_cast<AudioRegion*> (x->second);
2434 if (ar->region_list_equivalent (*oar)) {
2439 if (x == audio_regions.end()) {
2441 pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry;
2443 entry.first = region->id();
2446 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2457 fatal << _("programming error: ")
2458 << X_("unknown region type passed to Session::add_region()")
2465 /* mark dirty because something has changed even if we didn't
2466 add the region to the region list.
2472 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2473 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2474 AudioRegionAdded (ar); /* EMIT SIGNAL */
2479 Session::region_changed (Change what_changed, Region* region)
2481 if (what_changed & Region::HiddenChanged) {
2482 /* relay hidden changes */
2483 RegionHiddenChange (region);
2488 Session::region_renamed (Region* region)
2490 add_region (region);
2494 Session::remove_region (Region* region)
2496 AudioRegionList::iterator i;
2497 AudioRegion* ar = 0;
2498 bool removed = false;
2501 Glib::Mutex::Lock lm (region_lock);
2503 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2504 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2505 audio_regions.erase (i);
2509 fatal << _("programming error: ")
2510 << X_("unknown region type passed to Session::remove_region()")
2516 /* mark dirty because something has changed even if we didn't
2517 remove the region from the region list.
2523 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2528 Session::find_whole_file_parent (AudioRegion& child)
2530 AudioRegionList::iterator i;
2531 AudioRegion* region;
2532 Glib::Mutex::Lock lm (region_lock);
2534 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2536 region = (*i).second;
2538 if (region->whole_file()) {
2540 if (child.source_equivalent (*region)) {
2550 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2552 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2556 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2560 pl->get_region_list_equivalent_regions (region, result);
2565 Session::destroy_region (Region* region)
2567 AudioRegion* aregion;
2569 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2573 if (aregion->playlist()) {
2574 aregion->playlist()->destroy_region (region);
2577 vector<Source*> srcs;
2579 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2580 srcs.push_back (&aregion->source (n));
2583 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2585 if ((*i)->use_cnt() == 0) {
2586 (*i)->mark_for_remove ();
2595 Session::destroy_regions (list<Region*> regions)
2597 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2598 destroy_region (*i);
2604 Session::remove_last_capture ()
2608 Glib::RWLock::ReaderLock lm (diskstream_lock);
2610 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2611 list<Region*>& l = (*i)->last_capture_regions();
2614 r.insert (r.end(), l.begin(), l.end());
2619 destroy_regions (r);
2624 Session::remove_region_from_region_list (Region& r)
2630 /* Source Management */
2633 Session::add_source (Source* source)
2635 pair<SourceList::key_type, SourceList::mapped_type> entry;
2638 Glib::Mutex::Lock lm (source_lock);
2639 entry.first = source->id();
2640 entry.second = source;
2641 sources.insert (entry);
2644 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2647 SourceAdded (source); /* EMIT SIGNAL */
2651 Session::remove_source (Source* source)
2653 SourceList::iterator i;
2656 Glib::Mutex::Lock lm (source_lock);
2658 if ((i = sources.find (source->id())) != sources.end()) {
2663 if (!_state_of_the_state & InCleanup) {
2665 /* save state so we don't end up with a session file
2666 referring to non-existent sources.
2669 save_state (_current_snapshot_name);
2672 SourceRemoved(source); /* EMIT SIGNAL */
2676 Session::get_source (ARDOUR::id_t id)
2678 Glib::Mutex::Lock lm (source_lock);
2679 SourceList::iterator i;
2682 if ((i = sources.find (id)) != sources.end()) {
2683 source = (*i).second;
2690 Session::peak_path_from_audio_path (string audio_path)
2692 /* XXX hardly bombproof! fix me */
2696 res = Glib::path_get_dirname (audio_path);
2697 res = Glib::path_get_dirname (res);
2699 res += peak_dir_name;
2701 res += PBD::basename_nosuffix (audio_path);
2708 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2711 string old_basename = PBD::basename_nosuffix (oldname);
2712 string new_legalized = legalize_for_path (newname);
2714 /* note: we know (or assume) the old path is already valid */
2718 /* destructive file sources have a name of the form:
2720 /path/to/Tnnnn-NAME(%[LR])?.wav
2722 the task here is to replace NAME with the new name.
2725 /* find last slash */
2729 string::size_type slash;
2730 string::size_type dash;
2732 if ((slash = path.find_last_of ('/')) == string::npos) {
2736 dir = path.substr (0, slash+1);
2738 /* '-' is not a legal character for the NAME part of the path */
2740 if ((dash = path.find_last_of ('-')) == string::npos) {
2744 prefix = path.substr (slash+1, dash-(slash+1));
2749 path += new_legalized;
2750 path += ".wav"; /* XXX gag me with a spoon */
2754 /* non-destructive file sources have a name of the form:
2756 /path/to/NAME-nnnnn(%[LR])?.wav
2758 the task here is to replace NAME with the new name.
2761 /* find last slash */
2765 string::size_type slash;
2766 string::size_type dash;
2768 if ((slash = path.find_last_of ('/')) == string::npos) {
2772 dir = path.substr (0, slash+1);
2774 /* '-' is not a legal character for the NAME part of the path */
2776 if ((dash = path.find_last_of ('-')) == string::npos) {
2780 suffix = path.substr (dash);
2783 path += new_legalized;
2791 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2795 char buf[PATH_MAX+1];
2796 const uint32_t limit = 10000;
2800 legalized = legalize_for_path (name);
2802 /* find a "version" of the file name that doesn't exist in
2803 any of the possible directories.
2806 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2808 vector<space_and_path>::iterator i;
2809 uint32_t existing = 0;
2811 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2816 spath += tape_dir_name;
2818 spath += sound_dir_name;
2823 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2824 } else if (nchan == 2) {
2826 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2828 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2830 } else if (nchan < 26) {
2831 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2833 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2841 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2842 } else if (nchan == 2) {
2844 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2846 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2848 } else if (nchan < 26) {
2849 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2851 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2855 if (access (buf, F_OK) == 0) {
2860 if (existing == 0) {
2865 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2866 throw failed_constructor();
2870 /* we now have a unique name for the file, but figure out where to
2877 spath = tape_dir ();
2879 spath = discover_best_sound_dir ();
2882 string::size_type pos = foo.find_last_of ('/');
2884 if (pos == string::npos) {
2887 spath += foo.substr (pos + 1);
2894 Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
2896 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2898 /* this might throw failed_constructor(), which is OK */
2901 return new DestructiveFileSource (spath, frame_rate(), false, Config->get_native_file_data_format());
2903 return new FileSource (spath, frame_rate(), false, Config->get_native_file_data_format());
2907 /* Playlist management */
2910 Session::get_playlist (string name)
2914 if ((ret = playlist_by_name (name)) == 0) {
2915 ret = new AudioPlaylist (*this, name);
2922 Session::playlist_by_name (string name)
2924 Glib::Mutex::Lock lm (playlist_lock);
2925 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2926 if ((*i)->name() == name) {
2930 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2931 if ((*i)->name() == name) {
2939 Session::add_playlist (Playlist* playlist)
2941 if (playlist->hidden()) {
2946 Glib::Mutex::Lock lm (playlist_lock);
2947 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2948 playlists.insert (playlists.begin(), playlist);
2950 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2951 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2957 PlaylistAdded (playlist); /* EMIT SIGNAL */
2961 Session::track_playlist (Playlist* pl, bool inuse)
2963 PlaylistList::iterator x;
2966 Glib::Mutex::Lock lm (playlist_lock);
2969 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2971 unused_playlists.insert (pl);
2973 if ((x = playlists.find (pl)) != playlists.end()) {
2974 playlists.erase (x);
2979 //cerr << "shifting playlist to used: " << pl->name() << endl;
2981 playlists.insert (pl);
2983 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
2984 unused_playlists.erase (x);
2991 Session::remove_playlist (Playlist* playlist)
2993 if (_state_of_the_state & Deletion) {
2998 Glib::Mutex::Lock lm (playlist_lock);
2999 // cerr << "removing playlist: " << playlist->name() << endl;
3001 PlaylistList::iterator i;
3003 i = find (playlists.begin(), playlists.end(), playlist);
3005 if (i != playlists.end()) {
3006 playlists.erase (i);
3009 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3010 if (i != unused_playlists.end()) {
3011 unused_playlists.erase (i);
3018 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3022 Session::set_audition (AudioRegion* r)
3024 pending_audition_region = r;
3025 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3026 schedule_butler_transport_work ();
3030 Session::non_realtime_set_audition ()
3032 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3033 auditioner->audition_current_playlist ();
3034 } else if (pending_audition_region) {
3035 auditioner->audition_region (*pending_audition_region);
3037 pending_audition_region = 0;
3038 AuditionActive (true); /* EMIT SIGNAL */
3042 Session::audition_playlist ()
3044 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3045 ev->set_ptr ((void*) 0xfeedface);
3050 Session::audition_region (AudioRegion& r)
3052 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3058 Session::cancel_audition ()
3060 if (auditioner->active()) {
3061 auditioner->cancel_audition ();
3062 AuditionActive (false); /* EMIT SIGNAL */
3067 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
3069 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3073 Session::remove_empty_sounds ()
3076 PathScanner scanner;
3081 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3083 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3085 if (FileSource::is_empty (*(*i))) {
3087 unlink ((*i)->c_str());
3089 string peak_path = peak_path_from_audio_path (**i);
3090 unlink (peak_path.c_str());
3096 delete possible_audiofiles;
3100 Session::is_auditioning () const
3102 /* can be called before we have an auditioner object */
3104 return auditioner->active();
3111 Session::set_all_solo (bool yn)
3114 Glib::RWLock::ReaderLock lm (route_lock);
3116 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3117 if (!(*i)->hidden()) {
3118 (*i)->set_solo (yn, this);
3127 Session::set_all_mute (bool yn)
3130 Glib::RWLock::ReaderLock lm (route_lock);
3132 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3133 if (!(*i)->hidden()) {
3134 (*i)->set_mute (yn, this);
3143 Session::n_diskstreams () const
3145 Glib::RWLock::ReaderLock lm (diskstream_lock);
3148 for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3149 if (!(*i)->hidden()) {
3157 Session::foreach_diskstream (void (DiskStream::*func)(void))
3159 Glib::RWLock::ReaderLock lm (diskstream_lock);
3160 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3161 if (!(*i)->hidden()) {
3168 Session::graph_reordered ()
3170 /* don't do this stuff if we are setting up connections
3171 from a set_state() call.
3174 if (_state_of_the_state & InitialConnecting) {
3178 Glib::RWLock::WriterLock lm1 (route_lock);
3179 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3183 /* force all diskstreams to update their capture offset values to
3184 reflect any changes in latencies within the graph.
3187 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3188 (*i)->set_capture_offset ();
3193 Session::record_disenable_all ()
3195 record_enable_change_all (false);
3199 Session::record_enable_all ()
3201 record_enable_change_all (true);
3205 Session::record_enable_change_all (bool yn)
3207 Glib::RWLock::ReaderLock lm1 (route_lock);
3209 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3212 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3213 at->set_record_enable (yn, this);
3217 /* since we don't keep rec-enable state, don't mark session dirty */
3221 Session::add_redirect (Redirect* redirect)
3225 PortInsert* port_insert;
3226 PluginInsert* plugin_insert;
3228 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3229 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3230 _port_inserts.insert (_port_inserts.begin(), port_insert);
3231 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3232 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3234 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3237 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3238 _sends.insert (_sends.begin(), send);
3240 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3244 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3250 Session::remove_redirect (Redirect* redirect)
3254 PortInsert* port_insert;
3255 PluginInsert* plugin_insert;
3257 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3258 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3259 _port_inserts.remove (port_insert);
3260 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3261 _plugin_inserts.remove (plugin_insert);
3263 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3266 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3267 _sends.remove (send);
3269 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3277 Session::available_capture_duration ()
3279 const double scale = 4096.0 / sizeof (Sample);
3281 if (_total_free_4k_blocks * scale > (double) max_frames) {
3285 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3289 Session::add_connection (ARDOUR::Connection* connection)
3292 Glib::Mutex::Lock guard (connection_lock);
3293 _connections.push_back (connection);
3296 ConnectionAdded (connection); /* EMIT SIGNAL */
3302 Session::remove_connection (ARDOUR::Connection* connection)
3304 bool removed = false;
3307 Glib::Mutex::Lock guard (connection_lock);
3308 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3310 if (i != _connections.end()) {
3311 _connections.erase (i);
3317 ConnectionRemoved (connection); /* EMIT SIGNAL */
3323 ARDOUR::Connection *
3324 Session::connection_by_name (string name) const
3326 Glib::Mutex::Lock lm (connection_lock);
3328 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3329 if ((*i)->name() == name) {
3338 Session::set_edit_mode (EditMode mode)
3343 Glib::Mutex::Lock lm (playlist_lock);
3345 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3346 (*i)->set_edit_mode (mode);
3351 ControlChanged (EditingMode); /* EMIT SIGNAL */
3355 Session::tempo_map_changed (Change ignored)
3362 Session::ensure_passthru_buffers (uint32_t howmany)
3364 while (howmany > _passthru_buffers.size()) {
3366 #ifdef NO_POSIX_MEMALIGN
3367 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3369 posix_memalign((void **)&p,16,current_block_size * 4);
3371 _passthru_buffers.push_back (p);
3375 #ifdef NO_POSIX_MEMALIGN
3376 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3378 posix_memalign((void **)&p,16,current_block_size * 4);
3380 memset (p, 0, sizeof (Sample) * current_block_size);
3381 _silent_buffers.push_back (p);
3385 #ifdef NO_POSIX_MEMALIGN
3386 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3388 posix_memalign((void **)&p,16,current_block_size * 4);
3390 memset (p, 0, sizeof (Sample) * current_block_size);
3391 _send_buffers.push_back (p);
3394 allocate_pan_automation_buffers (current_block_size, howmany, false);
3398 Session::next_send_name ()
3401 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3406 Session::next_insert_name ()
3409 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3413 /* Named Selection management */
3416 Session::named_selection_by_name (string name)
3418 Glib::Mutex::Lock lm (named_selection_lock);
3419 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3420 if ((*i)->name == name) {
3428 Session::add_named_selection (NamedSelection* named_selection)
3431 Glib::Mutex::Lock lm (named_selection_lock);
3432 named_selections.insert (named_selections.begin(), named_selection);
3437 NamedSelectionAdded (); /* EMIT SIGNAL */
3441 Session::remove_named_selection (NamedSelection* named_selection)
3443 bool removed = false;
3446 Glib::Mutex::Lock lm (named_selection_lock);
3448 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3450 if (i != named_selections.end()) {
3452 named_selections.erase (i);
3459 NamedSelectionRemoved (); /* EMIT SIGNAL */
3464 Session::reset_native_file_format ()
3466 // jlc - WHY take routelock?
3467 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3468 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3470 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3471 (*i)->reset_write_sources (false);
3476 Session::route_name_unique (string n) const
3478 Glib::RWLock::ReaderLock lm (route_lock);
3480 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3481 if ((*i)->name() == n) {
3490 Session::remove_file_source (FileSource& fs)
3492 return fs.move_to_trash (dead_sound_dir_name);
3496 Session::n_playlists () const
3498 Glib::Mutex::Lock lm (playlist_lock);
3499 return playlists.size();
3503 Session::set_solo_model (SoloModel sm)
3505 if (sm != _solo_model) {
3507 ControlChanged (SoloingModel);
3513 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3515 if (!force && howmany <= _npan_buffers) {
3519 if (_pan_automation_buffer) {
3521 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3522 delete [] _pan_automation_buffer[i];
3525 delete [] _pan_automation_buffer;
3528 _pan_automation_buffer = new pan_t*[howmany];
3530 for (uint32_t i = 0; i < howmany; ++i) {
3531 _pan_automation_buffer[i] = new pan_t[nframes];
3534 _npan_buffers = howmany;
3538 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3540 Stateful::add_instant_xml (node, dir);
3541 Config->add_instant_xml (node, get_user_ardour_path());
3545 Session::freeze (InterThreadInfo& itt)
3547 Glib::RWLock::ReaderLock lm (route_lock);
3549 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3553 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3554 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3565 Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len, bool overwrite, vector<Source*>& srcs,
3566 InterThreadInfo& itt)
3570 FileSource* fsource;
3572 char buf[PATH_MAX+1];
3575 jack_nframes_t position;
3576 jack_nframes_t this_chunk;
3577 jack_nframes_t to_do;
3578 vector<Sample*> buffers;
3580 const jack_nframes_t chunk_size = (256 * 1024)/4;
3582 g_atomic_int_set (&processing_prohibited, 1);
3584 /* call tree *MUST* hold route_lock */
3586 if ((playlist = track.disk_stream().playlist()) == 0) {
3590 /* external redirects will be a problem */
3592 if (track.has_external_redirects()) {
3596 nchans = track.disk_stream().n_channels();
3598 dir = discover_best_sound_dir ();
3600 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3602 for (x = 0; x < 99999; ++x) {
3603 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3604 if (access (buf, F_OK) != 0) {
3610 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3615 fsource = new FileSource (buf, frame_rate(), false, Config->get_native_file_data_format());
3618 catch (failed_constructor& err) {
3619 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3623 srcs.push_back(fsource);
3626 /* XXX need to flush all redirects */
3631 /* create a set of reasonably-sized buffers */
3633 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3635 #ifdef NO_POSIX_MEMALIGN
3636 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3638 posix_memalign((void **)&b,16,chunk_size * 4);
3640 buffers.push_back (b);
3643 workbuf = new char[chunk_size * 4];
3645 while (to_do && !itt.cancel) {
3647 this_chunk = min (to_do, chunk_size);
3649 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3654 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3655 if ((*src)->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3660 start += this_chunk;
3661 to_do -= this_chunk;
3663 itt.progress = (float) (1.0 - ((double) to_do / len));
3672 xnow = localtime (&now);
3674 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3675 dynamic_cast<FileSource*>((*src))->update_header (position, *xnow, now);
3678 /* build peakfile for new source */
3680 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3681 dynamic_cast<FileSource*>(*src)->build_peaks ();
3689 for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3690 dynamic_cast<FileSource*>(*src)->mark_for_remove ();
3695 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3703 g_atomic_int_set (&processing_prohibited, 0);
3711 Session::get_silent_buffers (uint32_t howmany)
3713 for (uint32_t i = 0; i < howmany; ++i) {
3714 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3716 return _silent_buffers;
3720 Session::ntracks () const
3723 Glib::RWLock::ReaderLock lm (route_lock);
3725 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3726 if (dynamic_cast<AudioTrack*> (*i)) {
3735 Session::nbusses () const
3738 Glib::RWLock::ReaderLock lm (route_lock);
3740 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3741 if (dynamic_cast<AudioTrack*> (*i) == 0) {
3750 Session::set_layer_model (LayerModel lm)
3752 if (lm != layer_model) {
3755 ControlChanged (LayeringModel);
3760 Session::set_xfade_model (CrossfadeModel xm)
3762 if (xm != xfade_model) {
3765 ControlChanged (CrossfadingModel);