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 <glibmm/thread.h>
36 #include <glibmm/miscutils.h>
38 #include <pbd/error.h>
39 #include <glibmm/thread.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/stl_delete.h>
42 #include <pbd/basename.h>
44 #include <ardour/audioengine.h>
45 #include <ardour/configuration.h>
46 #include <ardour/session.h>
47 #include <ardour/audio_diskstream.h>
48 #include <ardour/utils.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/destructive_filesource.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>
69 #include <ardour/osc.h>
75 using namespace ARDOUR;
78 const char* Session::_template_suffix = X_(".template");
79 const char* Session::_statefile_suffix = X_(".ardour");
80 const char* Session::_pending_suffix = X_(".pending");
81 const char* Session::sound_dir_name = X_("sounds");
82 const char* Session::tape_dir_name = X_("tapes");
83 const char* Session::peak_dir_name = X_("peaks");
84 const char* Session::dead_sound_dir_name = X_("dead_sounds");
86 Session::compute_peak_t Session::compute_peak = 0;
87 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
88 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
89 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
91 sigc::signal<int> Session::AskAboutPendingState;
92 sigc::signal<void> Session::SMPTEOffsetChanged;
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 audio_diskstreams\n";
459 #endif /* TRACK_DESTRUCTION */
460 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ) {
461 AudioDiskstreamList::iterator tmp;
471 #ifdef TRACK_DESTRUCTION
472 cerr << "delete audio sources\n";
473 #endif /* TRACK_DESTRUCTION */
474 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
475 AudioSourceList::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 (AudioDiskstream* 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 (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_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 (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_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 (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_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 audio_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 (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_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 (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_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 (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_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));
1435 // XXX we need some equivalent to this, somehow
1436 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1440 /* XXX need to reset/reinstantiate all LADSPA plugins */
1444 Session::set_block_size (jack_nframes_t nframes)
1446 /* the AudioEngine guarantees
1447 that it will not be called while we are also in
1448 ::process(). It is therefore fine to do things that block
1453 Glib::RWLock::ReaderLock lm (route_lock);
1454 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1455 vector<Sample*>::iterator i;
1458 current_block_size = nframes;
1460 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1464 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1468 _passthru_buffers.clear ();
1469 _silent_buffers.clear ();
1471 ensure_passthru_buffers (np);
1473 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1477 #ifdef NO_POSIX_MEMALIGN
1478 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1480 posix_memalign((void **)&buf,16,current_block_size * 4);
1484 memset (*i, 0, sizeof (Sample) * current_block_size);
1488 if (_gain_automation_buffer) {
1489 delete [] _gain_automation_buffer;
1491 _gain_automation_buffer = new gain_t[nframes];
1493 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1495 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1496 (*i)->set_block_size (nframes);
1499 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
1500 (*i)->set_block_size (nframes);
1503 set_worst_io_latencies (false);
1508 Session::set_default_fade (float steepness, float fade_msecs)
1511 jack_nframes_t fade_frames;
1513 /* Don't allow fade of less 1 frame */
1515 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1522 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1526 default_fade_msecs = fade_msecs;
1527 default_fade_steepness = steepness;
1530 // jlc, WTF is this!
1531 Glib::RWLock::ReaderLock lm (route_lock);
1532 AudioRegion::set_default_fade (steepness, fade_frames);
1537 /* XXX have to do this at some point */
1538 /* foreach region using default fade, reset, then
1539 refill_all_diskstream_buffers ();
1544 struct RouteSorter {
1545 bool operator() (Route* r1, Route* r2) {
1546 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1548 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1551 if (r1->fed_by.empty()) {
1552 if (r2->fed_by.empty()) {
1553 /* no ardour-based connections inbound to either route. just use signal order */
1554 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1556 /* r2 has connections, r1 does not; run r1 early */
1560 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1567 trace_terminal (Route* r1, Route* rbase)
1571 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1572 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1576 /* make a copy of the existing list of routes that feed r1 */
1578 set<Route *> existing = r1->fed_by;
1580 /* for each route that feeds r1, recurse, marking it as feeding
1584 for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
1587 /* r2 is a route that feeds r1 which somehow feeds base. mark
1588 base as being fed by r2
1591 rbase->fed_by.insert (r2);
1595 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1599 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1603 /* now recurse, so that we can mark base as being fed by
1604 all routes that feed r2
1607 trace_terminal (r2, rbase);
1614 Session::resort_routes (void* src)
1616 /* don't do anything here with signals emitted
1617 by Routes while we are being destroyed.
1620 if (_state_of_the_state & Deletion) {
1624 /* Caller MUST hold the route_lock */
1626 RouteList::iterator i, j;
1628 for (i = routes.begin(); i != routes.end(); ++i) {
1630 (*i)->fed_by.clear ();
1632 for (j = routes.begin(); j != routes.end(); ++j) {
1634 /* although routes can feed themselves, it will
1635 cause an endless recursive descent if we
1636 detect it. so don't bother checking for
1644 if ((*j)->feeds (*i)) {
1645 (*i)->fed_by.insert (*j);
1650 for (i = routes.begin(); i != routes.end(); ++i) {
1651 trace_terminal (*i, *i);
1658 cerr << "finished route resort\n";
1660 for (i = routes.begin(); i != routes.end(); ++i) {
1661 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1669 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1672 char track_name[32];
1674 uint32_t channels_used = 0;
1676 uint32_t nphysical_in;
1677 uint32_t nphysical_out;
1679 /* count existing audio tracks */
1682 Glib::RWLock::ReaderLock lm (route_lock);
1683 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1684 if (dynamic_cast<AudioTrack*>(*i) != 0) {
1685 if (!(*i)->hidden()) {
1687 channels_used += (*i)->n_inputs();
1693 /* check for duplicate route names, since we might have pre-existing
1694 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1695 save, close,restart,add new route - first named route is now
1700 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1701 if (route_by_name (track_name) == 0) {
1706 } while (n < (UINT_MAX-1));
1708 if (input_auto_connect & AutoConnectPhysical) {
1709 nphysical_in = n_physical_inputs;
1714 if (output_auto_connect & AutoConnectPhysical) {
1715 nphysical_out = n_physical_outputs;
1721 track = new AudioTrack (*this, track_name, Route::Flag (0), mode);
1723 if (track->ensure_io (input_channels, output_channels, false, this)) {
1724 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1725 input_channels, output_channels)
1730 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1734 if (input_auto_connect & AutoConnectPhysical) {
1735 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1738 if (port.length() && track->connect_input (track->input (x), port, this)) {
1744 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1748 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1749 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1750 } else if (output_auto_connect & AutoConnectMaster) {
1752 port = _master_out->input (x%_master_out->n_inputs())->name();
1756 if (port.length() && track->connect_output (track->output (x), port, this)) {
1762 vector<string> cports;
1763 uint32_t ni = _control_out->n_inputs();
1765 for (n = 0; n < ni; ++n) {
1766 cports.push_back (_control_out->input(n)->name());
1769 track->set_control_outs (cports);
1772 track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
1776 track->set_remote_control_id (ntracks());
1779 catch (failed_constructor &err) {
1780 error << _("Session: could not create new audio track.") << endmsg;
1788 Session::new_audio_route (int input_channels, int output_channels)
1795 /* count existing audio busses */
1798 Glib::RWLock::ReaderLock lm (route_lock);
1799 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
1800 if (dynamic_cast<AudioTrack*>(*i) == 0) {
1801 if (!(*i)->hidden()) {
1809 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1810 if (route_by_name (bus_name) == 0) {
1815 } while (n < (UINT_MAX-1));
1818 bus = new Route (*this, bus_name, -1, -1, -1, -1);
1820 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1821 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1822 input_channels, output_channels)
1826 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1830 if (input_auto_connect & AutoConnectPhysical) {
1831 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1834 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1839 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1843 if (output_auto_connect & AutoConnectPhysical) {
1844 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1845 } else if (output_auto_connect & AutoConnectMaster) {
1847 port = _master_out->input (x%_master_out->n_inputs())->name();
1851 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1857 vector<string> cports;
1858 uint32_t ni = _control_out->n_inputs();
1860 for (uint32_t n = 0; n < ni; ++n) {
1861 cports.push_back (_control_out->input(n)->name());
1863 bus->set_control_outs (cports);
1869 catch (failed_constructor &err) {
1870 error << _("Session: could not create new route.") << endmsg;
1878 Session::add_route (Route* route)
1881 Glib::RWLock::WriterLock lm (route_lock);
1882 routes.push_front (route);
1886 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1887 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1888 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1889 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1891 if (route->master()) {
1892 _master_out = route;
1895 if (route->control()) {
1896 _control_out = route;
1900 save_state (_current_snapshot_name);
1902 RouteAdded (route); /* EMIT SIGNAL */
1906 Session::add_diskstream (AudioDiskstream* dstream)
1908 /* need to do this in case we're rolling at the time, to prevent false underruns */
1909 dstream->do_refill(0, 0, 0);
1912 Glib::RWLock::WriterLock lm (diskstream_lock);
1913 audio_diskstreams.push_back (dstream);
1916 /* take a reference to the diskstream, preventing it from
1917 ever being deleted until the session itself goes away,
1918 or chooses to remove it for its own purposes.
1922 dstream->set_block_size (current_block_size);
1924 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1925 /* this will connect to future changes, and check the current length */
1926 diskstream_playlist_changed (dstream);
1928 dstream->prepare ();
1931 save_state (_current_snapshot_name);
1933 AudioDiskstreamAdded (dstream); /* EMIT SIGNAL */
1937 Session::remove_route (Route& route)
1940 Glib::RWLock::WriterLock lm (route_lock);
1941 routes.remove (&route);
1943 /* deleting the master out seems like a dumb
1944 idea, but its more of a UI policy issue
1948 if (&route == _master_out) {
1952 if (&route == _control_out) {
1955 /* cancel control outs for all routes */
1957 vector<string> empty;
1959 for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
1960 (*r)->set_control_outs (empty);
1964 update_route_solo_state ();
1968 AudioDiskstream* ds = 0;
1970 if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
1971 ds = &at->disk_stream();
1977 Glib::RWLock::WriterLock lm (diskstream_lock);
1978 audio_diskstreams.remove (ds);
1984 find_current_end ();
1986 update_latency_compensation (false, false);
1989 /* XXX should we disconnect from the Route's signals ? */
1991 save_state (_current_snapshot_name);
1997 Session::route_mute_changed (void* src)
2003 Session::route_solo_changed (void* src, Route* route)
2005 if (solo_update_disabled) {
2010 Glib::RWLock::ReaderLock lm (route_lock);
2013 is_track = (dynamic_cast<AudioTrack*>(route) != 0);
2015 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2017 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2021 /* don't mess with busses */
2023 if (dynamic_cast<AudioTrack*>(*i) == 0) {
2029 /* don't mess with tracks */
2031 if (dynamic_cast<AudioTrack*>(*i) != 0) {
2036 if ((*i) != route &&
2037 ((*i)->mix_group () == 0 ||
2038 (*i)->mix_group () != route->mix_group () ||
2039 !route->mix_group ()->is_active())) {
2041 if ((*i)->soloed()) {
2043 /* if its already soloed, and solo latching is enabled,
2044 then leave it as it is.
2047 if (_solo_latched) {
2054 solo_update_disabled = true;
2055 (*i)->set_solo (false, src);
2056 solo_update_disabled = false;
2060 bool something_soloed = false;
2061 bool same_thing_soloed = false;
2062 bool signal = false;
2064 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2065 if ((*i)->soloed()) {
2066 something_soloed = true;
2067 if (dynamic_cast<AudioTrack*>(*i)) {
2069 same_thing_soloed = true;
2074 same_thing_soloed = true;
2082 if (something_soloed != currently_soloing) {
2084 currently_soloing = something_soloed;
2087 modify_solo_mute (is_track, same_thing_soloed);
2090 SoloActive (currently_soloing);
2097 Session::set_solo_latched (bool yn)
2099 if (yn != _solo_latched) {
2102 ControlChanged (SoloLatch);
2107 Session::update_route_solo_state ()
2110 bool is_track = false;
2111 bool signal = false;
2113 /* caller must hold RouteLock */
2115 /* this is where we actually implement solo by changing
2116 the solo mute setting of each track.
2119 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2120 if ((*i)->soloed()) {
2122 if (dynamic_cast<AudioTrack*>(*i)) {
2129 if (mute != currently_soloing) {
2131 currently_soloing = mute;
2134 if (!is_track && !mute) {
2136 /* nothing is soloed */
2138 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2139 (*i)->set_solo_mute (false);
2149 modify_solo_mute (is_track, mute);
2152 SoloActive (currently_soloing);
2157 Session::modify_solo_mute (bool is_track, bool mute)
2159 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2163 /* only alter track solo mute */
2165 if (dynamic_cast<AudioTrack*>(*i)) {
2166 if ((*i)->soloed()) {
2167 (*i)->set_solo_mute (!mute);
2169 (*i)->set_solo_mute (mute);
2175 /* only alter bus solo mute */
2177 if (!dynamic_cast<AudioTrack*>(*i)) {
2179 if ((*i)->soloed()) {
2181 (*i)->set_solo_mute (false);
2185 /* don't mute master or control outs
2186 in response to another bus solo
2189 if ((*i) != _master_out &&
2190 (*i) != _control_out) {
2191 (*i)->set_solo_mute (mute);
2202 Session::catch_up_on_solo ()
2204 /* this is called after set_state() to catch the full solo
2205 state, which can't be correctly determined on a per-route
2206 basis, but needs the global overview that only the session
2209 Glib::RWLock::ReaderLock lm (route_lock);
2210 update_route_solo_state();
2214 Session::route_by_name (string name)
2216 Glib::RWLock::ReaderLock lm (route_lock);
2218 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2219 if ((*i)->name() == name) {
2228 Session::route_by_remote_id (uint32_t id)
2230 Glib::RWLock::ReaderLock lm (route_lock);
2232 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2233 if ((*i)->remote_control_id() == id) {
2242 Session::find_current_end ()
2244 if (_state_of_the_state & Loading) {
2248 jack_nframes_t max = get_maximum_extent ();
2250 if (max > end_location->end()) {
2251 end_location->set_end (max);
2253 DurationChanged(); /* EMIT SIGNAL */
2258 Session::get_maximum_extent () const
2260 jack_nframes_t max = 0;
2263 /* Don't take the diskstream lock. Caller must have other ways to
2267 for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2268 Playlist* pl = (*i)->playlist();
2269 if ((me = pl->get_maximum_extent()) > max) {
2278 Session::diskstream_by_name (string name)
2280 Glib::RWLock::ReaderLock lm (diskstream_lock);
2282 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2283 if ((*i)->name() == name) {
2292 Session::diskstream_by_id (id_t id)
2294 Glib::RWLock::ReaderLock lm (diskstream_lock);
2296 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2297 if ((*i)->id() == id) {
2305 /* AudioRegion management */
2308 Session::new_region_name (string old)
2310 string::size_type last_period;
2312 string::size_type len = old.length() + 64;
2315 if ((last_period = old.find_last_of ('.')) == string::npos) {
2317 /* no period present - add one explicitly */
2320 last_period = old.length() - 1;
2325 number = atoi (old.substr (last_period+1).c_str());
2329 while (number < (UINT_MAX-1)) {
2331 AudioRegionList::const_iterator i;
2336 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2339 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2340 if ((*i).second->name() == sbuf) {
2345 if (i == audio_regions.end()) {
2350 if (number != (UINT_MAX-1)) {
2354 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2359 Session::region_name (string& result, string base, bool newlevel) const
2366 Glib::Mutex::Lock lm (region_lock);
2368 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2376 /* XXX this is going to be slow. optimize me later */
2381 string::size_type pos;
2383 pos = base.find_last_of ('.');
2385 /* pos may be npos, but then we just use entire base */
2387 subbase = base.substr (0, pos);
2391 bool name_taken = true;
2394 Glib::Mutex::Lock lm (region_lock);
2396 for (int n = 1; n < 5000; ++n) {
2399 snprintf (buf, sizeof (buf), ".%d", n);
2404 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2405 if ((*i).second->name() == result) {
2418 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2426 Session::add_region (Region* region)
2428 AudioRegion* ar = 0;
2429 AudioRegion* oar = 0;
2433 Glib::Mutex::Lock lm (region_lock);
2435 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2437 AudioRegionList::iterator x;
2439 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2441 oar = dynamic_cast<AudioRegion*> (x->second);
2443 if (ar->region_list_equivalent (*oar)) {
2448 if (x == audio_regions.end()) {
2450 pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry;
2452 entry.first = region->id();
2455 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2466 fatal << _("programming error: ")
2467 << X_("unknown region type passed to Session::add_region()")
2474 /* mark dirty because something has changed even if we didn't
2475 add the region to the region list.
2481 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2482 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2483 AudioRegionAdded (ar); /* EMIT SIGNAL */
2488 Session::region_changed (Change what_changed, Region* region)
2490 if (what_changed & Region::HiddenChanged) {
2491 /* relay hidden changes */
2492 RegionHiddenChange (region);
2497 Session::region_renamed (Region* region)
2499 add_region (region);
2503 Session::remove_region (Region* region)
2505 AudioRegionList::iterator i;
2506 AudioRegion* ar = 0;
2507 bool removed = false;
2510 Glib::Mutex::Lock lm (region_lock);
2512 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2513 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2514 audio_regions.erase (i);
2518 fatal << _("programming error: ")
2519 << X_("unknown region type passed to Session::remove_region()")
2525 /* mark dirty because something has changed even if we didn't
2526 remove the region from the region list.
2532 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2537 Session::find_whole_file_parent (AudioRegion& child)
2539 AudioRegionList::iterator i;
2540 AudioRegion* region;
2541 Glib::Mutex::Lock lm (region_lock);
2543 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2545 region = (*i).second;
2547 if (region->whole_file()) {
2549 if (child.source_equivalent (*region)) {
2559 Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
2561 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2565 if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
2569 pl->get_region_list_equivalent_regions (region, result);
2574 Session::destroy_region (Region* region)
2576 AudioRegion* aregion;
2578 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2582 if (aregion->playlist()) {
2583 aregion->playlist()->destroy_region (region);
2586 vector<Source*> srcs;
2588 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2589 srcs.push_back (&aregion->source (n));
2592 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2594 if ((*i)->use_cnt() == 0) {
2595 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2597 (afs)->mark_for_remove ();
2607 Session::destroy_regions (list<Region*> regions)
2609 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2610 destroy_region (*i);
2616 Session::remove_last_capture ()
2620 Glib::RWLock::ReaderLock lm (diskstream_lock);
2622 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
2623 list<Region*>& l = (*i)->last_capture_regions();
2626 r.insert (r.end(), l.begin(), l.end());
2631 destroy_regions (r);
2636 Session::remove_region_from_region_list (Region& r)
2642 /* Source Management */
2645 Session::add_audio_source (AudioSource* source)
2647 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2650 Glib::Mutex::Lock lm (audio_source_lock);
2651 entry.first = source->id();
2652 entry.second = source;
2653 audio_sources.insert (entry);
2656 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2659 SourceAdded (source); /* EMIT SIGNAL */
2663 Session::remove_source (Source* source)
2665 AudioSourceList::iterator i;
2668 Glib::Mutex::Lock lm (audio_source_lock);
2670 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2671 audio_sources.erase (i);
2675 if (!_state_of_the_state & InCleanup) {
2677 /* save state so we don't end up with a session file
2678 referring to non-existent sources.
2681 save_state (_current_snapshot_name);
2684 SourceRemoved(source); /* EMIT SIGNAL */
2688 Session::get_source (ARDOUR::id_t id)
2690 Glib::Mutex::Lock lm (audio_source_lock);
2691 AudioSourceList::iterator i;
2694 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2695 source = (*i).second;
2702 /* XXX search MIDI or other searches here */
2708 Session::peak_path_from_audio_path (string audio_path)
2710 /* XXX hardly bombproof! fix me */
2714 res = Glib::path_get_dirname (audio_path);
2715 res = Glib::path_get_dirname (res);
2717 res += peak_dir_name;
2719 res += PBD::basename_nosuffix (audio_path);
2726 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2729 string old_basename = PBD::basename_nosuffix (oldname);
2730 string new_legalized = legalize_for_path (newname);
2732 /* note: we know (or assume) the old path is already valid */
2736 /* destructive file sources have a name of the form:
2738 /path/to/Tnnnn-NAME(%[LR])?.wav
2740 the task here is to replace NAME with the new name.
2743 /* find last slash */
2747 string::size_type slash;
2748 string::size_type dash;
2750 if ((slash = path.find_last_of ('/')) == string::npos) {
2754 dir = path.substr (0, slash+1);
2756 /* '-' is not a legal character for the NAME part of the path */
2758 if ((dash = path.find_last_of ('-')) == string::npos) {
2762 prefix = path.substr (slash+1, dash-(slash+1));
2767 path += new_legalized;
2768 path += ".wav"; /* XXX gag me with a spoon */
2772 /* non-destructive file sources have a name of the form:
2774 /path/to/NAME-nnnnn(%[LR])?.wav
2776 the task here is to replace NAME with the new name.
2779 /* find last slash */
2783 string::size_type slash;
2784 string::size_type dash;
2786 if ((slash = path.find_last_of ('/')) == string::npos) {
2790 dir = path.substr (0, slash+1);
2792 /* '-' is not a legal character for the NAME part of the path */
2794 if ((dash = path.find_last_of ('-')) == string::npos) {
2798 suffix = path.substr (dash);
2801 path += new_legalized;
2809 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2813 char buf[PATH_MAX+1];
2814 const uint32_t limit = 10000;
2818 legalized = legalize_for_path (name);
2820 /* find a "version" of the file name that doesn't exist in
2821 any of the possible directories.
2824 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2826 vector<space_and_path>::iterator i;
2827 uint32_t existing = 0;
2829 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2834 spath += tape_dir_name;
2836 spath += sound_dir_name;
2841 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2842 } else if (nchan == 2) {
2844 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2846 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2848 } else if (nchan < 26) {
2849 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2851 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2859 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2860 } else if (nchan == 2) {
2862 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2864 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2866 } else if (nchan < 26) {
2867 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2869 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2873 if (access (buf, F_OK) == 0) {
2878 if (existing == 0) {
2883 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2884 throw failed_constructor();
2888 /* we now have a unique name for the file, but figure out where to
2895 spath = tape_dir ();
2897 spath = discover_best_sound_dir ();
2900 string::size_type pos = foo.find_last_of ('/');
2902 if (pos == string::npos) {
2905 spath += foo.substr (pos + 1);
2912 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2914 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2916 /* this might throw failed_constructor(), which is OK */
2919 return new DestructiveFileSource (spath,
2920 Config->get_native_file_data_format(),
2921 Config->get_native_file_header_format(),
2924 return new SndFileSource (spath,
2925 Config->get_native_file_data_format(),
2926 Config->get_native_file_header_format(),
2931 /* Playlist management */
2934 Session::get_playlist (string name)
2938 if ((ret = playlist_by_name (name)) == 0) {
2939 ret = new AudioPlaylist (*this, name);
2946 Session::playlist_by_name (string name)
2948 Glib::Mutex::Lock lm (playlist_lock);
2949 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2950 if ((*i)->name() == name) {
2954 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2955 if ((*i)->name() == name) {
2963 Session::add_playlist (Playlist* playlist)
2965 if (playlist->hidden()) {
2970 Glib::Mutex::Lock lm (playlist_lock);
2971 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2972 playlists.insert (playlists.begin(), playlist);
2974 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2975 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2981 PlaylistAdded (playlist); /* EMIT SIGNAL */
2985 Session::track_playlist (Playlist* pl, bool inuse)
2987 PlaylistList::iterator x;
2990 Glib::Mutex::Lock lm (playlist_lock);
2993 //cerr << "shifting playlist to unused: " << pl->name() << endl;
2995 unused_playlists.insert (pl);
2997 if ((x = playlists.find (pl)) != playlists.end()) {
2998 playlists.erase (x);
3003 //cerr << "shifting playlist to used: " << pl->name() << endl;
3005 playlists.insert (pl);
3007 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3008 unused_playlists.erase (x);
3015 Session::remove_playlist (Playlist* playlist)
3017 if (_state_of_the_state & Deletion) {
3022 Glib::Mutex::Lock lm (playlist_lock);
3023 // cerr << "removing playlist: " << playlist->name() << endl;
3025 PlaylistList::iterator i;
3027 i = find (playlists.begin(), playlists.end(), playlist);
3029 if (i != playlists.end()) {
3030 playlists.erase (i);
3033 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3034 if (i != unused_playlists.end()) {
3035 unused_playlists.erase (i);
3042 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3046 Session::set_audition (AudioRegion* r)
3048 pending_audition_region = r;
3049 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3050 schedule_butler_transport_work ();
3054 Session::non_realtime_set_audition ()
3056 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3057 auditioner->audition_current_playlist ();
3058 } else if (pending_audition_region) {
3059 auditioner->audition_region (*pending_audition_region);
3061 pending_audition_region = 0;
3062 AuditionActive (true); /* EMIT SIGNAL */
3066 Session::audition_playlist ()
3068 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3069 ev->set_ptr ((void*) 0xfeedface);
3074 Session::audition_region (AudioRegion& r)
3076 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3082 Session::cancel_audition ()
3084 if (auditioner->active()) {
3085 auditioner->cancel_audition ();
3086 AuditionActive (false); /* EMIT SIGNAL */
3091 Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
3093 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3097 Session::remove_empty_sounds ()
3100 PathScanner scanner;
3105 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3107 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3109 if (AudioFileSource::is_empty (*(*i))) {
3111 unlink ((*i)->c_str());
3113 string peak_path = peak_path_from_audio_path (**i);
3114 unlink (peak_path.c_str());
3120 delete possible_audiofiles;
3124 Session::is_auditioning () const
3126 /* can be called before we have an auditioner object */
3128 return auditioner->active();
3135 Session::set_all_solo (bool yn)
3138 Glib::RWLock::ReaderLock lm (route_lock);
3140 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3141 if (!(*i)->hidden()) {
3142 (*i)->set_solo (yn, this);
3151 Session::set_all_mute (bool yn)
3154 Glib::RWLock::ReaderLock lm (route_lock);
3156 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3157 if (!(*i)->hidden()) {
3158 (*i)->set_mute (yn, this);
3167 Session::n_audio_diskstreams () const
3169 Glib::RWLock::ReaderLock lm (diskstream_lock);
3172 for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3173 if (!(*i)->hidden()) {
3181 Session::foreach_audio_diskstream (void (AudioDiskstream::*func)(void))
3183 Glib::RWLock::ReaderLock lm (diskstream_lock);
3184 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3185 if (!(*i)->hidden()) {
3192 Session::graph_reordered ()
3194 /* don't do this stuff if we are setting up connections
3195 from a set_state() call.
3198 if (_state_of_the_state & InitialConnecting) {
3202 Glib::RWLock::WriterLock lm1 (route_lock);
3203 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3207 /* force all diskstreams to update their capture offset values to
3208 reflect any changes in latencies within the graph.
3211 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3212 (*i)->set_capture_offset ();
3217 Session::record_disenable_all ()
3219 record_enable_change_all (false);
3223 Session::record_enable_all ()
3225 record_enable_change_all (true);
3229 Session::record_enable_change_all (bool yn)
3231 Glib::RWLock::ReaderLock lm1 (route_lock);
3233 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3236 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3237 at->set_record_enable (yn, this);
3241 /* since we don't keep rec-enable state, don't mark session dirty */
3245 Session::add_redirect (Redirect* redirect)
3249 PortInsert* port_insert;
3250 PluginInsert* plugin_insert;
3252 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3253 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3254 _port_inserts.insert (_port_inserts.begin(), port_insert);
3255 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3256 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3258 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3261 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3262 _sends.insert (_sends.begin(), send);
3264 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3268 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3274 Session::remove_redirect (Redirect* redirect)
3278 PortInsert* port_insert;
3279 PluginInsert* plugin_insert;
3281 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3282 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3283 _port_inserts.remove (port_insert);
3284 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3285 _plugin_inserts.remove (plugin_insert);
3287 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3290 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3291 _sends.remove (send);
3293 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3301 Session::available_capture_duration ()
3303 const double scale = 4096.0 / sizeof (Sample);
3305 if (_total_free_4k_blocks * scale > (double) max_frames) {
3309 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3313 Session::add_connection (ARDOUR::Connection* connection)
3316 Glib::Mutex::Lock guard (connection_lock);
3317 _connections.push_back (connection);
3320 ConnectionAdded (connection); /* EMIT SIGNAL */
3326 Session::remove_connection (ARDOUR::Connection* connection)
3328 bool removed = false;
3331 Glib::Mutex::Lock guard (connection_lock);
3332 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3334 if (i != _connections.end()) {
3335 _connections.erase (i);
3341 ConnectionRemoved (connection); /* EMIT SIGNAL */
3347 ARDOUR::Connection *
3348 Session::connection_by_name (string name) const
3350 Glib::Mutex::Lock lm (connection_lock);
3352 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3353 if ((*i)->name() == name) {
3362 Session::set_edit_mode (EditMode mode)
3367 Glib::Mutex::Lock lm (playlist_lock);
3369 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3370 (*i)->set_edit_mode (mode);
3375 ControlChanged (EditingMode); /* EMIT SIGNAL */
3379 Session::tempo_map_changed (Change ignored)
3386 Session::ensure_passthru_buffers (uint32_t howmany)
3388 while (howmany > _passthru_buffers.size()) {
3390 #ifdef NO_POSIX_MEMALIGN
3391 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3393 posix_memalign((void **)&p,16,current_block_size * 4);
3395 _passthru_buffers.push_back (p);
3399 #ifdef NO_POSIX_MEMALIGN
3400 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3402 posix_memalign((void **)&p,16,current_block_size * 4);
3404 memset (p, 0, sizeof (Sample) * current_block_size);
3405 _silent_buffers.push_back (p);
3409 #ifdef NO_POSIX_MEMALIGN
3410 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3412 posix_memalign((void **)&p,16,current_block_size * 4);
3414 memset (p, 0, sizeof (Sample) * current_block_size);
3415 _send_buffers.push_back (p);
3418 allocate_pan_automation_buffers (current_block_size, howmany, false);
3422 Session::next_send_name ()
3425 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3430 Session::next_insert_name ()
3433 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3437 /* Named Selection management */
3440 Session::named_selection_by_name (string name)
3442 Glib::Mutex::Lock lm (named_selection_lock);
3443 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3444 if ((*i)->name == name) {
3452 Session::add_named_selection (NamedSelection* named_selection)
3455 Glib::Mutex::Lock lm (named_selection_lock);
3456 named_selections.insert (named_selections.begin(), named_selection);
3461 NamedSelectionAdded (); /* EMIT SIGNAL */
3465 Session::remove_named_selection (NamedSelection* named_selection)
3467 bool removed = false;
3470 Glib::Mutex::Lock lm (named_selection_lock);
3472 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3474 if (i != named_selections.end()) {
3476 named_selections.erase (i);
3483 NamedSelectionRemoved (); /* EMIT SIGNAL */
3488 Session::reset_native_file_format ()
3490 // jlc - WHY take routelock?
3491 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3492 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3494 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
3495 (*i)->reset_write_sources (false);
3500 Session::route_name_unique (string n) const
3502 Glib::RWLock::ReaderLock lm (route_lock);
3504 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3505 if ((*i)->name() == n) {
3514 Session::cleanup_audio_file_source (AudioFileSource& fs)
3516 return fs.move_to_trash (dead_sound_dir_name);
3520 Session::n_playlists () const
3522 Glib::Mutex::Lock lm (playlist_lock);
3523 return playlists.size();
3527 Session::set_solo_model (SoloModel sm)
3529 if (sm != _solo_model) {
3531 ControlChanged (SoloingModel);
3537 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3539 if (!force && howmany <= _npan_buffers) {
3543 if (_pan_automation_buffer) {
3545 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3546 delete [] _pan_automation_buffer[i];
3549 delete [] _pan_automation_buffer;
3552 _pan_automation_buffer = new pan_t*[howmany];
3554 for (uint32_t i = 0; i < howmany; ++i) {
3555 _pan_automation_buffer[i] = new pan_t[nframes];
3558 _npan_buffers = howmany;
3562 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3564 Stateful::add_instant_xml (node, dir);
3565 Config->add_instant_xml (node, get_user_ardour_path());
3569 Session::freeze (InterThreadInfo& itt)
3571 Glib::RWLock::ReaderLock lm (route_lock);
3573 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
3577 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
3578 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3589 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3590 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3594 AudioFileSource* fsource;
3596 char buf[PATH_MAX+1];
3599 jack_nframes_t position;
3600 jack_nframes_t this_chunk;
3601 jack_nframes_t to_do;
3602 vector<Sample*> buffers;
3605 // any bigger than this seems to cause stack overflows in called functions
3606 const jack_nframes_t chunk_size = (128 * 1024)/4;
3608 g_atomic_int_set (&processing_prohibited, 1);
3610 /* call tree *MUST* hold route_lock */
3612 if ((playlist = track.disk_stream().playlist()) == 0) {
3616 /* external redirects will be a problem */
3618 if (track.has_external_redirects()) {
3622 nchans = track.disk_stream().n_channels();
3624 dir = discover_best_sound_dir ();
3626 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3628 for (x = 0; x < 99999; ++x) {
3629 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3630 if (access (buf, F_OK) != 0) {
3636 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3641 fsource = new SndFileSource (buf,
3642 Config->get_native_file_data_format(),
3643 Config->get_native_file_header_format(),
3648 catch (failed_constructor& err) {
3649 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3653 srcs.push_back(fsource);
3656 /* XXX need to flush all redirects */
3661 /* create a set of reasonably-sized buffers */
3663 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3665 #ifdef NO_POSIX_MEMALIGN
3666 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3668 posix_memalign((void **)&b,16,chunk_size * 4);
3670 buffers.push_back (b);
3673 workbuf = new char[chunk_size * 4];
3675 while (to_do && !itt.cancel) {
3677 this_chunk = min (to_do, chunk_size);
3679 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3684 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3685 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3688 if (afs->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3694 start += this_chunk;
3695 to_do -= this_chunk;
3697 itt.progress = (float) (1.0 - ((double) to_do / len));
3706 xnow = localtime (&now);
3708 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3709 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3711 afs->update_header (position, *xnow, now);
3715 /* build peakfile for new source */
3717 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3718 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3720 afs->build_peaks ();
3729 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3730 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3732 afs->mark_for_remove ();
3738 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3746 g_atomic_int_set (&processing_prohibited, 0);
3754 Session::get_silent_buffers (uint32_t howmany)
3756 for (uint32_t i = 0; i < howmany; ++i) {
3757 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3759 return _silent_buffers;
3763 Session::ntracks () const
3766 Glib::RWLock::ReaderLock lm (route_lock);
3768 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3769 if (dynamic_cast<AudioTrack*> (*i)) {
3778 Session::nbusses () const
3781 Glib::RWLock::ReaderLock lm (route_lock);
3783 for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
3784 if (dynamic_cast<AudioTrack*> (*i) == 0) {
3793 Session::set_layer_model (LayerModel lm)
3795 if (lm != layer_model) {
3798 ControlChanged (LayeringModel);
3803 Session::set_xfade_model (CrossfadeModel xm)
3805 if (xm != xfade_model) {
3808 ControlChanged (CrossfadingModel);