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>
67 #include <ardour/data_type.h>
70 #include <ardour/osc.h>
76 using namespace ARDOUR;
78 using boost::shared_ptr;
80 const char* Session::_template_suffix = X_(".template");
81 const char* Session::_statefile_suffix = X_(".ardour");
82 const char* Session::_pending_suffix = X_(".pending");
83 const char* Session::sound_dir_name = X_("sounds");
84 const char* Session::tape_dir_name = X_("tapes");
85 const char* Session::peak_dir_name = X_("peaks");
86 const char* Session::dead_sound_dir_name = X_("dead_sounds");
88 Session::compute_peak_t Session::compute_peak = 0;
89 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
90 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
91 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
93 sigc::signal<int> Session::AskAboutPendingState;
94 sigc::signal<void> Session::SMPTEOffsetChanged;
95 sigc::signal<void> Session::SendFeedback;
99 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
102 char buf[PATH_MAX+1];
106 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
107 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
113 /* check to see if it exists, and what it is */
115 if (stat (str.c_str(), &statbuf)) {
116 if (errno == ENOENT) {
119 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
127 /* it exists, so it must either be the name
128 of the directory, or the name of the statefile
132 if (S_ISDIR (statbuf.st_mode)) {
134 string::size_type slash = str.find_last_of ('/');
136 if (slash == string::npos) {
138 /* a subdirectory of cwd, so statefile should be ... */
144 tmp += _statefile_suffix;
148 if (stat (tmp.c_str(), &statbuf)) {
149 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
159 /* some directory someplace in the filesystem.
160 the snapshot name is the directory name
165 snapshot = str.substr (slash+1);
169 } else if (S_ISREG (statbuf.st_mode)) {
171 string::size_type slash = str.find_last_of ('/');
172 string::size_type suffix;
174 /* remove the suffix */
176 if (slash != string::npos) {
177 snapshot = str.substr (slash+1);
182 suffix = snapshot.find (_statefile_suffix);
184 if (suffix == string::npos) {
185 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
191 snapshot = snapshot.substr (0, suffix);
193 if (slash == string::npos) {
195 /* we must be in the directory where the
196 statefile lives. get it using cwd().
199 char cwd[PATH_MAX+1];
201 if (getcwd (cwd, sizeof (cwd)) == 0) {
202 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
211 /* full path to the statefile */
213 path = str.substr (0, slash);
218 /* what type of file is it? */
219 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
225 /* its the name of a new directory. get the name
229 string::size_type slash = str.find_last_of ('/');
231 if (slash == string::npos) {
233 /* no slash, just use the name, but clean it up */
235 path = legalize_for_path (str);
241 snapshot = str.substr (slash+1);
248 Session::Session (AudioEngine &eng,
250 string snapshot_name,
251 string* mix_template)
254 _mmc_port (default_mmc_port),
255 _mtc_port (default_mtc_port),
256 _midi_port (default_midi_port),
257 pending_events (2048),
258 midi_requests (128), // the size of this should match the midi request pool size
259 routes (new RouteList),
260 auditioner ((Auditioner*) 0),
266 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
268 n_physical_outputs = _engine.n_physical_outputs();
269 n_physical_inputs = _engine.n_physical_inputs();
271 first_stage_init (fullpath, snapshot_name);
273 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
274 throw failed_constructor ();
277 if (second_stage_init (new_session)) {
278 throw failed_constructor ();
281 store_recent_sessions(_name, _path);
283 bool was_dirty = dirty();
285 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
288 DirtyChanged (); /* EMIT SIGNAL */
292 Session::Session (AudioEngine &eng,
294 string snapshot_name,
295 AutoConnectOption input_ac,
296 AutoConnectOption output_ac,
297 uint32_t control_out_channels,
298 uint32_t master_out_channels,
299 uint32_t requested_physical_in,
300 uint32_t requested_physical_out,
301 jack_nframes_t initial_length)
304 _mmc_port (default_mmc_port),
305 _mtc_port (default_mtc_port),
306 _midi_port (default_midi_port),
307 pending_events (2048),
309 routes (new RouteList),
315 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << endl;
317 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
318 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
320 first_stage_init (fullpath, snapshot_name);
322 if (create (new_session, 0, initial_length)) {
323 throw failed_constructor ();
326 if (control_out_channels) {
327 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
332 if (master_out_channels) {
333 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
337 /* prohibit auto-connect to master, because there isn't one */
338 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
341 input_auto_connect = input_ac;
342 output_auto_connect = output_ac;
344 if (second_stage_init (new_session)) {
345 throw failed_constructor ();
348 store_recent_sessions(_name, _path);
350 bool was_dirty = dirty ();
352 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
355 DirtyChanged (); /* EMIT SIGNAL */
361 /* if we got to here, leaving pending capture state around
365 remove_pending_capture_state ();
367 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
368 _engine.remove_session ();
370 going_away (); /* EMIT SIGNAL */
372 terminate_butler_thread ();
373 terminate_midi_thread ();
375 if (click_data && click_data != default_click) {
376 delete [] click_data;
379 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
380 delete [] click_emphasis_data;
385 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
389 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
393 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
397 for (map<RunContext,char*>::iterator i = _conversion_buffers.begin(); i != _conversion_buffers.end(); ++i) {
398 delete [] (i->second);
401 AudioDiskstream::free_working_buffers();
403 #undef TRACK_DESTRUCTION
404 #ifdef TRACK_DESTRUCTION
405 cerr << "delete named selections\n";
406 #endif /* TRACK_DESTRUCTION */
407 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
408 NamedSelectionList::iterator tmp;
417 #ifdef TRACK_DESTRUCTION
418 cerr << "delete playlists\n";
419 #endif /* TRACK_DESTRUCTION */
420 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
421 PlaylistList::iterator tmp;
431 #ifdef TRACK_DESTRUCTION
432 cerr << "delete audio regions\n";
433 #endif /* TRACK_DESTRUCTION */
434 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
435 AudioRegionList::iterator tmp;
445 #ifdef TRACK_DESTRUCTION
446 cerr << "delete diskstreams\n";
447 #endif /* TRACK_DESTRUCTION */
448 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
449 DiskstreamList::iterator tmp;
459 #ifdef TRACK_DESTRUCTION
460 cerr << "delete audio sources\n";
461 #endif /* TRACK_DESTRUCTION */
462 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
463 AudioSourceList::iterator tmp;
473 #ifdef TRACK_DESTRUCTION
474 cerr << "delete mix groups\n";
475 #endif /* TRACK_DESTRUCTION */
476 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
477 list<RouteGroup*>::iterator tmp;
487 #ifdef TRACK_DESTRUCTION
488 cerr << "delete edit groups\n";
489 #endif /* TRACK_DESTRUCTION */
490 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
491 list<RouteGroup*>::iterator tmp;
501 #ifdef TRACK_DESTRUCTION
502 cerr << "delete connections\n";
503 #endif /* TRACK_DESTRUCTION */
504 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
505 ConnectionList::iterator tmp;
515 if (butler_mixdown_buffer) {
516 delete [] butler_mixdown_buffer;
519 if (butler_gain_buffer) {
520 delete [] butler_gain_buffer;
523 Crossfade::set_buffer_size (0);
535 Session::set_worst_io_latencies ()
537 _worst_output_latency = 0;
538 _worst_input_latency = 0;
540 if (!_engine.connected()) {
544 boost::shared_ptr<RouteList> r = routes.reader ();
546 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
547 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
548 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
553 Session::when_engine_running ()
555 string first_physical_output;
557 /* we don't want to run execute this again */
559 first_time_running.disconnect ();
561 set_block_size (_engine.frames_per_cycle());
562 set_frame_rate (_engine.frame_rate());
564 /* every time we reconnect, recompute worst case output latencies */
566 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
568 if (synced_to_jack()) {
569 _engine.transport_stop ();
572 if (Config->get_jack_time_master()) {
573 _engine.transport_locate (_transport_frame);
581 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
583 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
585 /* existing state for Click */
587 if (_click_io->set_state (*child->children().front()) == 0) {
589 _clicking = click_requested;
593 error << _("could not setup Click I/O") << endmsg;
599 /* default state for Click */
601 first_physical_output = _engine.get_nth_physical_output (0);
603 if (first_physical_output.length()) {
604 if (_click_io->add_output_port (first_physical_output, this)) {
605 // relax, even though its an error
607 _clicking = click_requested;
613 catch (failed_constructor& err) {
614 error << _("cannot setup Click I/O") << endmsg;
617 set_worst_io_latencies ();
620 ControlChanged (Clicking); /* EMIT SIGNAL */
623 if (auditioner == 0) {
625 /* we delay creating the auditioner till now because
626 it makes its own connections to ports named
627 in the ARDOUR_RC config file. the engine has
628 to be running for this to work.
632 auditioner.reset (new Auditioner (*this));
635 catch (failed_constructor& err) {
636 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
640 /* Create a set of Connection objects that map
641 to the physical outputs currently available
646 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
648 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
650 Connection* c = new OutputConnection (buf, true);
653 c->add_connection (0, _engine.get_nth_physical_output (np));
658 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
660 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
662 Connection* c = new InputConnection (buf, true);
665 c->add_connection (0, _engine.get_nth_physical_input (np));
672 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
674 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
676 Connection* c = new OutputConnection (buf, true);
680 c->add_connection (0, _engine.get_nth_physical_output (np));
681 c->add_connection (1, _engine.get_nth_physical_output (np+1));
686 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
688 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
690 Connection* c = new InputConnection (buf, true);
694 c->add_connection (0, _engine.get_nth_physical_input (np));
695 c->add_connection (1, _engine.get_nth_physical_input (np+1));
704 /* create master/control ports */
709 /* force the master to ignore any later call to this */
711 if (_master_out->pending_state_node) {
712 _master_out->ports_became_legal();
715 /* no panner resets till we are through */
717 _master_out->defer_pan_reset ();
719 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
720 if (_master_out->add_input_port ("", this)) {
721 error << _("cannot setup master inputs")
727 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
728 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
729 error << _("cannot setup master outputs")
736 _master_out->allow_pan_reset ();
740 Connection* c = new OutputConnection (_("Master Out"), true);
742 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
744 c->add_connection ((int) n, _master_out->input(n)->name());
751 /* catch up on send+insert cnts */
755 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
758 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
759 if (id > insert_cnt) {
767 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
770 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
777 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
779 /* hook us up to the engine */
781 _engine.set_session (this);
786 osc->set_session (*this);
789 _state_of_the_state = Clean;
791 DirtyChanged (); /* EMIT SIGNAL */
795 Session::hookup_io ()
797 /* stop graph reordering notifications from
798 causing resorts, etc.
801 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
803 /* Tell all IO objects to create their ports */
810 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
811 if (_control_out->add_input_port ("", this)) {
812 error << _("cannot setup control inputs")
818 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
819 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
820 error << _("cannot set up master outputs")
828 /* Tell all IO objects to connect themselves together */
830 IO::enable_connecting ();
832 /* Now reset all panners */
834 IO::reset_panners ();
836 /* Anyone who cares about input state, wake up and do something */
838 IOConnectionsComplete (); /* EMIT SIGNAL */
840 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
842 /* now handle the whole enchilada as if it was one
848 /* update mixer solo state */
854 Session::playlist_length_changed (Playlist* pl)
856 /* we can't just increase end_location->end() if pl->get_maximum_extent()
857 if larger. if the playlist used to be the longest playlist,
858 and its now shorter, we have to decrease end_location->end(). hence,
859 we have to iterate over all diskstreams and check the
860 playlists currently in use.
866 Session::diskstream_playlist_changed (Diskstream* dstream)
870 if ((playlist = dstream->playlist()) != 0) {
871 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
874 /* see comment in playlist_length_changed () */
879 Session::record_enabling_legal () const
881 /* this used to be in here, but survey says.... we don't need to restrict it */
882 // if (record_status() == Recording) {
893 Session::set_auto_play (bool yn)
895 if (auto_play != yn) {
898 ControlChanged (AutoPlay);
903 Session::set_auto_return (bool yn)
905 if (auto_return != yn) {
908 ControlChanged (AutoReturn);
913 Session::set_crossfades_active (bool yn)
915 if (crossfades_active != yn) {
916 crossfades_active = yn;
918 ControlChanged (CrossFadesActive);
923 Session::set_do_not_record_plugins (bool yn)
925 if (do_not_record_plugins != yn) {
926 do_not_record_plugins = yn;
928 ControlChanged (RecordingPlugins);
933 Session::set_auto_input (bool yn)
935 if (auto_input != yn) {
938 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
939 /* auto-input only makes a difference if we're rolling */
941 /* Even though this can called from RT context we are using
942 a non-tentative rwlock here, because the action must occur.
943 The rarity and short potential lock duration makes this "OK"
945 Glib::RWLock::ReaderLock dsm (diskstream_lock);
946 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
947 if ((*i)->record_enabled ()) {
948 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
949 (*i)->monitor_input (!auto_input);
955 ControlChanged (AutoInput);
960 Session::reset_input_monitor_state ()
962 if (transport_rolling()) {
963 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 (Config->get_use_hardware_monitoring() && !auto_input);
971 Glib::RWLock::ReaderLock dsm (diskstream_lock);
972 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
973 if ((*i)->record_enabled ()) {
974 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
975 (*i)->monitor_input (Config->get_use_hardware_monitoring());
983 Session::set_input_auto_connect (bool yn)
986 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
988 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
994 Session::get_input_auto_connect () const
996 return (input_auto_connect & AutoConnectPhysical);
1000 Session::set_output_auto_connect (AutoConnectOption aco)
1002 output_auto_connect = aco;
1007 Session::auto_punch_start_changed (Location* location)
1009 replace_event (Event::PunchIn, location->start());
1011 if (get_record_enabled() && get_punch_in()) {
1012 /* capture start has been changed, so save new pending state */
1013 save_state ("", true);
1019 Session::auto_punch_end_changed (Location* location)
1021 jack_nframes_t when_to_stop = location->end();
1022 // when_to_stop += _worst_output_latency + _worst_input_latency;
1023 replace_event (Event::PunchOut, when_to_stop);
1027 Session::auto_punch_changed (Location* location)
1029 jack_nframes_t when_to_stop = location->end();
1031 replace_event (Event::PunchIn, location->start());
1032 //when_to_stop += _worst_output_latency + _worst_input_latency;
1033 replace_event (Event::PunchOut, when_to_stop);
1037 Session::auto_loop_changed (Location* location)
1039 replace_event (Event::AutoLoop, location->end(), location->start());
1041 if (transport_rolling() && get_auto_loop()) {
1043 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1045 if (_transport_frame > location->end()) {
1046 // relocate to beginning of loop
1047 clear_events (Event::LocateRoll);
1049 request_locate (location->start(), true);
1052 else if (seamless_loop && !loop_changing) {
1054 // schedule a locate-roll to refill the diskstreams at the
1055 // previous loop end
1056 loop_changing = true;
1058 if (location->end() > last_loopend) {
1059 clear_events (Event::LocateRoll);
1060 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1067 last_loopend = location->end();
1072 Session::set_auto_punch_location (Location* location)
1076 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1077 auto_punch_start_changed_connection.disconnect();
1078 auto_punch_end_changed_connection.disconnect();
1079 auto_punch_changed_connection.disconnect();
1080 existing->set_auto_punch (false, this);
1081 remove_event (existing->start(), Event::PunchIn);
1082 clear_events (Event::PunchOut);
1083 auto_punch_location_changed (0);
1088 if (location == 0) {
1092 if (location->end() <= location->start()) {
1093 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1097 auto_punch_start_changed_connection.disconnect();
1098 auto_punch_end_changed_connection.disconnect();
1099 auto_punch_changed_connection.disconnect();
1101 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1102 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1103 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1105 location->set_auto_punch (true, this);
1106 auto_punch_location_changed (location);
1110 Session::set_punch_in (bool yn)
1112 if (punch_in == yn) {
1118 if ((location = _locations.auto_punch_location()) != 0) {
1119 if ((punch_in = yn) == true) {
1120 replace_event (Event::PunchIn, location->start());
1122 remove_event (location->start(), Event::PunchIn);
1127 ControlChanged (PunchIn); /* EMIT SIGNAL */
1131 Session::set_punch_out (bool yn)
1133 if (punch_out == yn) {
1139 if ((location = _locations.auto_punch_location()) != 0) {
1140 if ((punch_out = yn) == true) {
1141 replace_event (Event::PunchOut, location->end());
1143 clear_events (Event::PunchOut);
1148 ControlChanged (PunchOut); /* EMIT SIGNAL */
1152 Session::set_auto_loop_location (Location* location)
1156 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1157 auto_loop_start_changed_connection.disconnect();
1158 auto_loop_end_changed_connection.disconnect();
1159 auto_loop_changed_connection.disconnect();
1160 existing->set_auto_loop (false, this);
1161 remove_event (existing->end(), Event::AutoLoop);
1162 auto_loop_location_changed (0);
1167 if (location == 0) {
1171 if (location->end() <= location->start()) {
1172 error << _("Session: you can't use a mark for auto loop") << endmsg;
1176 last_loopend = location->end();
1178 auto_loop_start_changed_connection.disconnect();
1179 auto_loop_end_changed_connection.disconnect();
1180 auto_loop_changed_connection.disconnect();
1182 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1183 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1184 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1186 location->set_auto_loop (true, this);
1187 auto_loop_location_changed (location);
1191 Session::locations_added (Location* ignored)
1197 Session::locations_changed ()
1199 _locations.apply (*this, &Session::handle_locations_changed);
1203 Session::handle_locations_changed (Locations::LocationList& locations)
1205 Locations::LocationList::iterator i;
1207 bool set_loop = false;
1208 bool set_punch = false;
1210 for (i = locations.begin(); i != locations.end(); ++i) {
1214 if (location->is_auto_punch()) {
1215 set_auto_punch_location (location);
1218 if (location->is_auto_loop()) {
1219 set_auto_loop_location (location);
1226 set_auto_loop_location (0);
1229 set_auto_punch_location (0);
1236 Session::enable_record ()
1238 /* XXX really atomic compare+swap here */
1239 if (g_atomic_int_get (&_record_status) != Recording) {
1240 g_atomic_int_set (&_record_status, Recording);
1241 _last_record_location = _transport_frame;
1242 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1244 if (Config->get_use_hardware_monitoring() && auto_input) {
1245 /* Even though this can be called from RT context we are using
1246 a non-tentative rwlock here, because the action must occur.
1247 The rarity and short potential lock duration makes this "OK"
1249 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1251 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1252 if ((*i)->record_enabled ()) {
1253 (*i)->monitor_input (true);
1258 RecordStateChanged ();
1263 Session::disable_record (bool rt_context, bool force)
1267 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1269 if (!Config->get_latched_record_enable () || force) {
1270 g_atomic_int_set (&_record_status, Disabled);
1272 if (rs == Recording) {
1273 g_atomic_int_set (&_record_status, Enabled);
1277 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1279 if (Config->get_use_hardware_monitoring() && auto_input) {
1280 /* Even though this can be called from RT context we are using
1281 a non-tentative rwlock here, because the action must occur.
1282 The rarity and short potential lock duration makes this "OK"
1284 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1286 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1287 if ((*i)->record_enabled ()) {
1288 (*i)->monitor_input (false);
1293 RecordStateChanged (); /* emit signal */
1296 remove_pending_capture_state ();
1302 Session::step_back_from_record ()
1304 g_atomic_int_set (&_record_status, Enabled);
1306 if (Config->get_use_hardware_monitoring()) {
1307 /* Even though this can be called from RT context we are using
1308 a non-tentative rwlock here, because the action must occur.
1309 The rarity and short potential lock duration makes this "OK"
1311 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1313 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1314 if (auto_input && (*i)->record_enabled ()) {
1315 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1316 (*i)->monitor_input (false);
1323 Session::maybe_enable_record ()
1325 g_atomic_int_set (&_record_status, Enabled);
1327 /* XXX this save should really happen in another thread. its needed so that
1328 pending capture state can be recovered if we crash.
1331 save_state ("", true);
1334 if (_transport_speed) {
1339 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1340 RecordStateChanged (); /* EMIT SIGNAL */
1347 Session::audible_frame () const
1350 jack_nframes_t offset;
1353 /* the first of these two possible settings for "offset"
1354 mean that the audible frame is stationary until
1355 audio emerges from the latency compensation
1358 the second means that the audible frame is stationary
1359 until audio would emerge from a physical port
1360 in the absence of any plugin latency compensation
1363 offset = _worst_output_latency;
1365 if (offset > current_block_size) {
1366 offset -= current_block_size;
1368 /* XXX is this correct? if we have no external
1369 physical connections and everything is internal
1370 then surely this is zero? still, how
1371 likely is that anyway?
1373 offset = current_block_size;
1376 if (synced_to_jack()) {
1377 tf = _engine.transport_frame();
1379 tf = _transport_frame;
1382 if (_transport_speed == 0) {
1392 if (!non_realtime_work_pending()) {
1396 /* take latency into account */
1405 Session::set_frame_rate (jack_nframes_t frames_per_second)
1407 /** \fn void Session::set_frame_size(jack_nframes_t)
1408 the AudioEngine object that calls this guarantees
1409 that it will not be called while we are also in
1410 ::process(). Its fine to do things that block
1414 _current_frame_rate = frames_per_second;
1415 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1417 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1419 // XXX we need some equivalent to this, somehow
1420 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1424 /* XXX need to reset/reinstantiate all LADSPA plugins */
1428 Session::set_block_size (jack_nframes_t nframes)
1430 /* the AudioEngine guarantees
1431 that it will not be called while we are also in
1432 ::process(). It is therefore fine to do things that block
1437 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1438 vector<Sample*>::iterator i;
1441 current_block_size = nframes;
1443 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1447 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1451 _passthru_buffers.clear ();
1452 _silent_buffers.clear ();
1454 ensure_passthru_buffers (np);
1456 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1460 #ifdef NO_POSIX_MEMALIGN
1461 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1463 posix_memalign((void **)&buf,16,current_block_size * 4);
1467 memset (*i, 0, sizeof (Sample) * current_block_size);
1471 if (_gain_automation_buffer) {
1472 delete [] _gain_automation_buffer;
1474 _gain_automation_buffer = new gain_t[nframes];
1476 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1478 boost::shared_ptr<RouteList> r = routes.reader ();
1480 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1481 (*i)->set_block_size (nframes);
1484 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1485 (*i)->set_block_size (nframes);
1488 set_worst_io_latencies ();
1493 Session::set_default_fade (float steepness, float fade_msecs)
1496 jack_nframes_t fade_frames;
1498 /* Don't allow fade of less 1 frame */
1500 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1507 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1511 default_fade_msecs = fade_msecs;
1512 default_fade_steepness = steepness;
1515 // jlc, WTF is this!
1516 Glib::RWLock::ReaderLock lm (route_lock);
1517 AudioRegion::set_default_fade (steepness, fade_frames);
1522 /* XXX have to do this at some point */
1523 /* foreach region using default fade, reset, then
1524 refill_all_diskstream_buffers ();
1529 struct RouteSorter {
1530 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1531 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1533 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1536 if (r1->fed_by.empty()) {
1537 if (r2->fed_by.empty()) {
1538 /* no ardour-based connections inbound to either route. just use signal order */
1539 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1541 /* r2 has connections, r1 does not; run r1 early */
1545 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1552 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1554 shared_ptr<Route> r2;
1556 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1557 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1561 /* make a copy of the existing list of routes that feed r1 */
1563 set<shared_ptr<Route> > existing = r1->fed_by;
1565 /* for each route that feeds r1, recurse, marking it as feeding
1569 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1572 /* r2 is a route that feeds r1 which somehow feeds base. mark
1573 base as being fed by r2
1576 rbase->fed_by.insert (r2);
1580 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1584 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1588 /* now recurse, so that we can mark base as being fed by
1589 all routes that feed r2
1592 trace_terminal (r2, rbase);
1599 Session::resort_routes ()
1601 /* don't do anything here with signals emitted
1602 by Routes while we are being destroyed.
1605 if (_state_of_the_state & Deletion) {
1612 RCUWriter<RouteList> writer (routes);
1613 shared_ptr<RouteList> r = writer.get_copy ();
1614 resort_routes_using (r);
1615 /* writer goes out of scope and forces update */
1620 Session::resort_routes_using (shared_ptr<RouteList> r)
1622 RouteList::iterator i, j;
1624 for (i = r->begin(); i != r->end(); ++i) {
1626 (*i)->fed_by.clear ();
1628 for (j = r->begin(); j != r->end(); ++j) {
1630 /* although routes can feed themselves, it will
1631 cause an endless recursive descent if we
1632 detect it. so don't bother checking for
1640 if ((*j)->feeds (*i)) {
1641 (*i)->fed_by.insert (*j);
1646 for (i = r->begin(); i != r->end(); ++i) {
1647 trace_terminal (*i, *i);
1654 cerr << "finished route resort\n";
1656 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1657 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1664 shared_ptr<AudioTrack>
1665 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1667 char track_name[32];
1669 uint32_t channels_used = 0;
1671 uint32_t nphysical_in;
1672 uint32_t nphysical_out;
1674 /* count existing audio tracks */
1677 shared_ptr<RouteList> r = routes.reader ();
1679 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1680 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1681 if (!(*i)->hidden()) {
1683 channels_used += (*i)->n_inputs();
1689 /* check for duplicate route names, since we might have pre-existing
1690 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1691 save, close,restart,add new route - first named route is now
1696 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1697 if (route_by_name (track_name) == 0) {
1702 } while (n < (UINT_MAX-1));
1704 if (input_auto_connect & AutoConnectPhysical) {
1705 nphysical_in = n_physical_inputs;
1710 if (output_auto_connect & AutoConnectPhysical) {
1711 nphysical_out = n_physical_outputs;
1717 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1719 if (track->ensure_io (input_channels, output_channels, false, this)) {
1720 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1721 input_channels, output_channels)
1726 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1730 if (input_auto_connect & AutoConnectPhysical) {
1731 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1734 if (port.length() && track->connect_input (track->input (x), port, this)) {
1740 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1744 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1745 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1746 } else if (output_auto_connect & AutoConnectMaster) {
1748 port = _master_out->input (x%_master_out->n_inputs())->name();
1752 if (port.length() && track->connect_output (track->output (x), port, this)) {
1758 vector<string> cports;
1759 uint32_t ni = _control_out->n_inputs();
1761 for (n = 0; n < ni; ++n) {
1762 cports.push_back (_control_out->input(n)->name());
1765 track->set_control_outs (cports);
1768 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1772 track->set_remote_control_id (ntracks());
1776 catch (failed_constructor &err) {
1777 error << _("Session: could not create new audio track.") << endmsg;
1778 return shared_ptr<AudioTrack> ((AudioTrack*) 0);
1783 Session::new_audio_route (int input_channels, int output_channels)
1789 /* count existing audio busses */
1792 shared_ptr<RouteList> r = routes.reader ();
1794 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1795 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1796 if (!(*i)->hidden()) {
1804 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1805 if (route_by_name (bus_name) == 0) {
1810 } while (n < (UINT_MAX-1));
1813 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1815 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1816 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1817 input_channels, output_channels)
1821 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1825 if (input_auto_connect & AutoConnectPhysical) {
1826 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1829 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1834 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1838 if (output_auto_connect & AutoConnectPhysical) {
1839 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1840 } else if (output_auto_connect & AutoConnectMaster) {
1842 port = _master_out->input (x%_master_out->n_inputs())->name();
1846 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1852 vector<string> cports;
1853 uint32_t ni = _control_out->n_inputs();
1855 for (uint32_t n = 0; n < ni; ++n) {
1856 cports.push_back (_control_out->input(n)->name());
1858 bus->set_control_outs (cports);
1865 catch (failed_constructor &err) {
1866 error << _("Session: could not create new audio route.") << endmsg;
1867 return shared_ptr<Route> ((Route*) 0);
1872 Session::add_route (shared_ptr<Route> route)
1875 RCUWriter<RouteList> writer (routes);
1876 shared_ptr<RouteList> r = writer.get_copy ();
1877 r->push_front (route);
1878 resort_routes_using (r);
1881 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1882 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1883 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1884 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1886 if (route->master()) {
1887 _master_out = route;
1890 if (route->control()) {
1891 _control_out = route;
1895 save_state (_current_snapshot_name);
1896 save_history (_current_snapshot_name);
1898 RouteAdded (route); /* EMIT SIGNAL */
1902 Session::add_diskstream (Diskstream* dstream)
1904 /* need to do this in case we're rolling at the time, to prevent false underruns */
1905 dstream->do_refill_with_alloc();
1908 Glib::RWLock::WriterLock lm (diskstream_lock);
1909 diskstreams.push_back (dstream);
1912 /* take a reference to the diskstream, preventing it from
1913 ever being deleted until the session itself goes away,
1914 or chooses to remove it for its own purposes.
1918 dstream->set_block_size (current_block_size);
1920 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1921 /* this will connect to future changes, and check the current length */
1922 diskstream_playlist_changed (dstream);
1924 dstream->prepare ();
1927 save_state (_current_snapshot_name);
1928 save_history (_current_snapshot_name);
1930 DiskstreamAdded (dstream); /* EMIT SIGNAL */
1934 Session::remove_route (shared_ptr<Route> route)
1937 RCUWriter<RouteList> writer (routes);
1938 shared_ptr<RouteList> rs = writer.get_copy ();
1941 /* deleting the master out seems like a dumb
1942 idea, but its more of a UI policy issue
1946 if (route == _master_out) {
1947 _master_out = shared_ptr<Route> ((Route*) 0);
1950 if (route == _control_out) {
1951 _control_out = shared_ptr<Route> ((Route*) 0);
1953 /* cancel control outs for all routes */
1955 vector<string> empty;
1957 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1958 (*r)->set_control_outs (empty);
1962 update_route_solo_state ();
1964 /* writer goes out of scope, forces route list update */
1967 // FIXME: audio specific
1969 AudioDiskstream* ds = 0;
1971 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1972 ds = &at->audio_diskstream();
1978 Glib::RWLock::WriterLock lm (diskstream_lock);
1979 diskstreams.remove (ds);
1985 find_current_end ();
1987 update_latency_compensation (false, false);
1990 /* XXX should we disconnect from the Route's signals ? */
1992 save_state (_current_snapshot_name);
1993 save_history (_current_snapshot_name);
1995 /* all shared ptrs to route should go out of scope here */
1999 Session::route_mute_changed (void* src)
2005 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2007 if (solo_update_disabled) {
2014 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2016 shared_ptr<RouteList> r = routes.reader ();
2018 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2020 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2024 /* don't mess with busses */
2026 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2032 /* don't mess with tracks */
2034 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2039 if ((*i) != route &&
2040 ((*i)->mix_group () == 0 ||
2041 (*i)->mix_group () != route->mix_group () ||
2042 !route->mix_group ()->is_active())) {
2044 if ((*i)->soloed()) {
2046 /* if its already soloed, and solo latching is enabled,
2047 then leave it as it is.
2050 if (_solo_latched) {
2057 solo_update_disabled = true;
2058 (*i)->set_solo (false, src);
2059 solo_update_disabled = false;
2063 bool something_soloed = false;
2064 bool same_thing_soloed = false;
2065 bool signal = false;
2067 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2068 if ((*i)->soloed()) {
2069 something_soloed = true;
2070 if (dynamic_cast<AudioTrack*>((*i).get())) {
2072 same_thing_soloed = true;
2077 same_thing_soloed = true;
2085 if (something_soloed != currently_soloing) {
2087 currently_soloing = something_soloed;
2090 modify_solo_mute (is_track, same_thing_soloed);
2093 SoloActive (currently_soloing);
2100 Session::set_solo_latched (bool yn)
2102 if (yn != _solo_latched) {
2105 ControlChanged (SoloLatch);
2110 Session::update_route_solo_state ()
2113 bool is_track = false;
2114 bool signal = false;
2116 /* caller must hold RouteLock */
2118 /* this is where we actually implement solo by changing
2119 the solo mute setting of each track.
2122 shared_ptr<RouteList> r = routes.reader ();
2124 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2125 if ((*i)->soloed()) {
2127 if (dynamic_cast<AudioTrack*>((*i).get())) {
2134 if (mute != currently_soloing) {
2136 currently_soloing = mute;
2139 if (!is_track && !mute) {
2141 /* nothing is soloed */
2143 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2144 (*i)->set_solo_mute (false);
2154 modify_solo_mute (is_track, mute);
2157 SoloActive (currently_soloing);
2162 Session::modify_solo_mute (bool is_track, bool mute)
2164 shared_ptr<RouteList> r = routes.reader ();
2166 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2170 /* only alter track solo mute */
2172 if (dynamic_cast<AudioTrack*>((*i).get())) {
2173 if ((*i)->soloed()) {
2174 (*i)->set_solo_mute (!mute);
2176 (*i)->set_solo_mute (mute);
2182 /* only alter bus solo mute */
2184 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2186 if ((*i)->soloed()) {
2188 (*i)->set_solo_mute (false);
2192 /* don't mute master or control outs
2193 in response to another bus solo
2196 if ((*i) != _master_out &&
2197 (*i) != _control_out) {
2198 (*i)->set_solo_mute (mute);
2209 Session::catch_up_on_solo ()
2211 /* this is called after set_state() to catch the full solo
2212 state, which can't be correctly determined on a per-route
2213 basis, but needs the global overview that only the session
2216 update_route_solo_state();
2220 Session::route_by_name (string name)
2222 shared_ptr<RouteList> r = routes.reader ();
2224 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2225 if ((*i)->name() == name) {
2230 return shared_ptr<Route> ((Route*) 0);
2234 Session::route_by_remote_id (uint32_t id)
2236 shared_ptr<RouteList> r = routes.reader ();
2238 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2239 if ((*i)->remote_control_id() == id) {
2244 return shared_ptr<Route> ((Route*) 0);
2248 Session::find_current_end ()
2250 if (_state_of_the_state & Loading) {
2254 jack_nframes_t max = get_maximum_extent ();
2256 if (max > end_location->end()) {
2257 end_location->set_end (max);
2259 DurationChanged(); /* EMIT SIGNAL */
2264 Session::get_maximum_extent () const
2266 jack_nframes_t max = 0;
2269 /* Don't take the diskstream lock. Caller must have other ways to
2273 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2274 Playlist* pl = (*i)->playlist();
2275 if ((me = pl->get_maximum_extent()) > max) {
2284 Session::diskstream_by_name (string name)
2286 Glib::RWLock::ReaderLock lm (diskstream_lock);
2288 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2289 if ((*i)->name() == name) {
2298 Session::diskstream_by_id (const PBD::ID& id)
2300 Glib::RWLock::ReaderLock lm (diskstream_lock);
2302 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2303 if ((*i)->id() == id) {
2311 /* AudioRegion management */
2314 Session::new_region_name (string old)
2316 string::size_type last_period;
2318 string::size_type len = old.length() + 64;
2321 if ((last_period = old.find_last_of ('.')) == string::npos) {
2323 /* no period present - add one explicitly */
2326 last_period = old.length() - 1;
2331 number = atoi (old.substr (last_period+1).c_str());
2335 while (number < (UINT_MAX-1)) {
2337 AudioRegionList::const_iterator i;
2342 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2345 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2346 if (i->second->name() == sbuf) {
2351 if (i == audio_regions.end()) {
2356 if (number != (UINT_MAX-1)) {
2360 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2365 Session::region_name (string& result, string base, bool newlevel) const
2372 Glib::Mutex::Lock lm (region_lock);
2374 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2382 /* XXX this is going to be slow. optimize me later */
2387 string::size_type pos;
2389 pos = base.find_last_of ('.');
2391 /* pos may be npos, but then we just use entire base */
2393 subbase = base.substr (0, pos);
2397 bool name_taken = true;
2400 Glib::Mutex::Lock lm (region_lock);
2402 for (int n = 1; n < 5000; ++n) {
2405 snprintf (buf, sizeof (buf), ".%d", n);
2410 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2411 if (i->second->name() == result) {
2424 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2432 Session::add_region (Region* region)
2434 AudioRegion* ar = 0;
2435 AudioRegion* oar = 0;
2439 Glib::Mutex::Lock lm (region_lock);
2441 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2443 AudioRegionList::iterator x;
2445 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2447 oar = dynamic_cast<AudioRegion*> (x->second);
2449 if (ar->region_list_equivalent (*oar)) {
2454 if (x == audio_regions.end()) {
2456 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2458 entry.first = region->id();
2461 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2472 fatal << _("programming error: ")
2473 << X_("unknown region type passed to Session::add_region()")
2480 /* mark dirty because something has changed even if we didn't
2481 add the region to the region list.
2487 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2488 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2489 AudioRegionAdded (ar); /* EMIT SIGNAL */
2494 Session::region_changed (Change what_changed, Region* region)
2496 if (what_changed & Region::HiddenChanged) {
2497 /* relay hidden changes */
2498 RegionHiddenChange (region);
2503 Session::region_renamed (Region* region)
2505 add_region (region);
2509 Session::remove_region (Region* region)
2511 AudioRegionList::iterator i;
2512 AudioRegion* ar = 0;
2513 bool removed = false;
2516 Glib::Mutex::Lock lm (region_lock);
2518 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2519 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2520 audio_regions.erase (i);
2526 fatal << _("programming error: ")
2527 << X_("unknown region type passed to Session::remove_region()")
2533 /* mark dirty because something has changed even if we didn't
2534 remove the region from the region list.
2540 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2545 Session::find_whole_file_parent (AudioRegion& child)
2547 AudioRegionList::iterator i;
2548 AudioRegion* region;
2549 Glib::Mutex::Lock lm (region_lock);
2551 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2555 if (region->whole_file()) {
2557 if (child.source_equivalent (*region)) {
2567 Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
2569 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2570 (*i)->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 (DiskstreamList::iterator i = diskstreams.begin(); i != 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);
2682 save_history (_current_snapshot_name);
2685 SourceRemoved(source); /* EMIT SIGNAL */
2689 Session::source_by_id (const PBD::ID& id)
2691 Glib::Mutex::Lock lm (audio_source_lock);
2692 AudioSourceList::iterator i;
2695 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2699 /* XXX search MIDI or other searches here */
2705 Session::peak_path_from_audio_path (string audio_path)
2707 /* XXX hardly bombproof! fix me */
2711 res = Glib::path_get_dirname (audio_path);
2712 res = Glib::path_get_dirname (res);
2714 res += peak_dir_name;
2716 res += PBD::basename_nosuffix (audio_path);
2723 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2726 string old_basename = PBD::basename_nosuffix (oldname);
2727 string new_legalized = legalize_for_path (newname);
2729 /* note: we know (or assume) the old path is already valid */
2733 /* destructive file sources have a name of the form:
2735 /path/to/Tnnnn-NAME(%[LR])?.wav
2737 the task here is to replace NAME with the new name.
2740 /* find last slash */
2744 string::size_type slash;
2745 string::size_type dash;
2747 if ((slash = path.find_last_of ('/')) == string::npos) {
2751 dir = path.substr (0, slash+1);
2753 /* '-' is not a legal character for the NAME part of the path */
2755 if ((dash = path.find_last_of ('-')) == string::npos) {
2759 prefix = path.substr (slash+1, dash-(slash+1));
2764 path += new_legalized;
2765 path += ".wav"; /* XXX gag me with a spoon */
2769 /* non-destructive file sources have a name of the form:
2771 /path/to/NAME-nnnnn(%[LR])?.wav
2773 the task here is to replace NAME with the new name.
2778 string::size_type slash;
2779 string::size_type dash;
2780 string::size_type postfix;
2782 /* find last slash */
2784 if ((slash = path.find_last_of ('/')) == string::npos) {
2788 dir = path.substr (0, slash+1);
2790 /* '-' is not a legal character for the NAME part of the path */
2792 if ((dash = path.find_last_of ('-')) == string::npos) {
2796 suffix = path.substr (dash+1);
2798 // Suffix is now everything after the dash. Now we need to eliminate
2799 // the nnnnn part, which is done by either finding a '%' or a '.'
2801 postfix = suffix.find_last_of ("%");
2802 if (postfix == string::npos) {
2803 postfix = suffix.find_last_of ('.');
2806 if (postfix != string::npos) {
2807 suffix = suffix.substr (postfix);
2809 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2813 const uint32_t limit = 10000;
2814 char buf[PATH_MAX+1];
2816 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2818 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2820 if (access (buf, F_OK) != 0) {
2828 error << "FATAL ERROR! Could not find a " << endl;
2837 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2841 char buf[PATH_MAX+1];
2842 const uint32_t limit = 10000;
2846 legalized = legalize_for_path (name);
2848 /* find a "version" of the file name that doesn't exist in
2849 any of the possible directories.
2852 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2854 vector<space_and_path>::iterator i;
2855 uint32_t existing = 0;
2857 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2862 spath += tape_dir_name;
2864 spath += sound_dir_name;
2869 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2870 } else if (nchan == 2) {
2872 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2874 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2876 } else if (nchan < 26) {
2877 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2879 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2887 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2888 } else if (nchan == 2) {
2890 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2892 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2894 } else if (nchan < 26) {
2895 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2897 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2901 if (access (buf, F_OK) == 0) {
2906 if (existing == 0) {
2911 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2912 throw failed_constructor();
2916 /* we now have a unique name for the file, but figure out where to
2923 spath = tape_dir ();
2925 spath = discover_best_sound_dir ();
2928 string::size_type pos = foo.find_last_of ('/');
2930 if (pos == string::npos) {
2933 spath += foo.substr (pos + 1);
2940 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2942 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2944 /* this might throw failed_constructor(), which is OK */
2947 return new DestructiveFileSource (spath,
2948 Config->get_native_file_data_format(),
2949 Config->get_native_file_header_format(),
2952 return new SndFileSource (spath,
2953 Config->get_native_file_data_format(),
2954 Config->get_native_file_header_format(),
2959 /* Playlist management */
2962 Session::playlist_by_name (string name)
2964 Glib::Mutex::Lock lm (playlist_lock);
2965 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2966 if ((*i)->name() == name) {
2970 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2971 if ((*i)->name() == name) {
2979 Session::add_playlist (Playlist* playlist)
2981 if (playlist->hidden()) {
2986 Glib::Mutex::Lock lm (playlist_lock);
2987 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2988 playlists.insert (playlists.begin(), playlist);
2990 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2991 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2997 PlaylistAdded (playlist); /* EMIT SIGNAL */
3001 Session::track_playlist (Playlist* pl, bool inuse)
3003 PlaylistList::iterator x;
3006 Glib::Mutex::Lock lm (playlist_lock);
3009 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3011 unused_playlists.insert (pl);
3013 if ((x = playlists.find (pl)) != playlists.end()) {
3014 playlists.erase (x);
3019 //cerr << "shifting playlist to used: " << pl->name() << endl;
3021 playlists.insert (pl);
3023 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3024 unused_playlists.erase (x);
3031 Session::remove_playlist (Playlist* playlist)
3033 if (_state_of_the_state & Deletion) {
3038 Glib::Mutex::Lock lm (playlist_lock);
3039 // cerr << "removing playlist: " << playlist->name() << endl;
3041 PlaylistList::iterator i;
3043 i = find (playlists.begin(), playlists.end(), playlist);
3045 if (i != playlists.end()) {
3046 playlists.erase (i);
3049 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3050 if (i != unused_playlists.end()) {
3051 unused_playlists.erase (i);
3058 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3062 Session::set_audition (AudioRegion* r)
3064 pending_audition_region = r;
3065 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3066 schedule_butler_transport_work ();
3070 Session::non_realtime_set_audition ()
3072 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3073 auditioner->audition_current_playlist ();
3074 } else if (pending_audition_region) {
3075 auditioner->audition_region (*pending_audition_region);
3077 pending_audition_region = 0;
3078 AuditionActive (true); /* EMIT SIGNAL */
3082 Session::audition_playlist ()
3084 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3085 ev->set_ptr ((void*) 0xfeedface);
3090 Session::audition_region (Region& r)
3092 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
3094 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3101 Session::cancel_audition ()
3103 if (auditioner->active()) {
3104 auditioner->cancel_audition ();
3105 AuditionActive (false); /* EMIT SIGNAL */
3110 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3112 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3116 Session::remove_empty_sounds ()
3119 PathScanner scanner;
3124 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3126 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3128 if (AudioFileSource::is_empty (*(*i))) {
3130 unlink ((*i)->c_str());
3132 string peak_path = peak_path_from_audio_path (**i);
3133 unlink (peak_path.c_str());
3139 delete possible_audiofiles;
3143 Session::is_auditioning () const
3145 /* can be called before we have an auditioner object */
3147 return auditioner->active();
3154 Session::set_all_solo (bool yn)
3156 shared_ptr<RouteList> r = routes.reader ();
3158 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3159 if (!(*i)->hidden()) {
3160 (*i)->set_solo (yn, this);
3168 Session::set_all_mute (bool yn)
3170 shared_ptr<RouteList> r = routes.reader ();
3172 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3173 if (!(*i)->hidden()) {
3174 (*i)->set_mute (yn, this);
3182 Session::n_diskstreams () const
3184 Glib::RWLock::ReaderLock lm (diskstream_lock);
3187 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3188 if (!(*i)->hidden()) {
3196 Session::graph_reordered ()
3198 /* don't do this stuff if we are setting up connections
3199 from a set_state() call.
3202 if (_state_of_the_state & InitialConnecting) {
3206 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3210 /* force all diskstreams to update their capture offset values to
3211 reflect any changes in latencies within the graph.
3214 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3215 (*i)->set_capture_offset ();
3220 Session::record_disenable_all ()
3222 record_enable_change_all (false);
3226 Session::record_enable_all ()
3228 record_enable_change_all (true);
3232 Session::record_enable_change_all (bool yn)
3234 shared_ptr<RouteList> r = routes.reader ();
3236 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3239 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3240 at->set_record_enable (yn, this);
3244 /* since we don't keep rec-enable state, don't mark session dirty */
3248 Session::add_redirect (Redirect* redirect)
3252 PortInsert* port_insert;
3253 PluginInsert* plugin_insert;
3255 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3256 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3257 _port_inserts.insert (_port_inserts.begin(), port_insert);
3258 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3259 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3261 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3264 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3265 _sends.insert (_sends.begin(), send);
3267 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3271 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3277 Session::remove_redirect (Redirect* redirect)
3281 PortInsert* port_insert;
3282 PluginInsert* plugin_insert;
3284 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3285 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3286 _port_inserts.remove (port_insert);
3287 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3288 _plugin_inserts.remove (plugin_insert);
3290 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3293 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3294 _sends.remove (send);
3296 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3304 Session::available_capture_duration ()
3306 const double scale = 4096.0 / sizeof (Sample);
3308 if (_total_free_4k_blocks * scale > (double) max_frames) {
3312 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3316 Session::add_connection (ARDOUR::Connection* connection)
3319 Glib::Mutex::Lock guard (connection_lock);
3320 _connections.push_back (connection);
3323 ConnectionAdded (connection); /* EMIT SIGNAL */
3329 Session::remove_connection (ARDOUR::Connection* connection)
3331 bool removed = false;
3334 Glib::Mutex::Lock guard (connection_lock);
3335 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3337 if (i != _connections.end()) {
3338 _connections.erase (i);
3344 ConnectionRemoved (connection); /* EMIT SIGNAL */
3350 ARDOUR::Connection *
3351 Session::connection_by_name (string name) const
3353 Glib::Mutex::Lock lm (connection_lock);
3355 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3356 if ((*i)->name() == name) {
3365 Session::set_edit_mode (EditMode mode)
3370 Glib::Mutex::Lock lm (playlist_lock);
3372 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3373 (*i)->set_edit_mode (mode);
3378 ControlChanged (EditingMode); /* EMIT SIGNAL */
3382 Session::tempo_map_changed (Change ignored)
3389 Session::ensure_passthru_buffers (uint32_t howmany)
3391 while (howmany > _passthru_buffers.size()) {
3393 #ifdef NO_POSIX_MEMALIGN
3394 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3396 posix_memalign((void **)&p,16,current_block_size * 4);
3398 _passthru_buffers.push_back (p);
3402 #ifdef NO_POSIX_MEMALIGN
3403 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3405 posix_memalign((void **)&p,16,current_block_size * 4);
3407 memset (p, 0, sizeof (Sample) * current_block_size);
3408 _silent_buffers.push_back (p);
3412 #ifdef NO_POSIX_MEMALIGN
3413 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3415 posix_memalign((void **)&p,16,current_block_size * 4);
3417 memset (p, 0, sizeof (Sample) * current_block_size);
3418 _send_buffers.push_back (p);
3421 allocate_pan_automation_buffers (current_block_size, howmany, false);
3425 Session::next_send_name ()
3428 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3433 Session::next_insert_name ()
3436 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3440 /* Named Selection management */
3443 Session::named_selection_by_name (string name)
3445 Glib::Mutex::Lock lm (named_selection_lock);
3446 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3447 if ((*i)->name == name) {
3455 Session::add_named_selection (NamedSelection* named_selection)
3458 Glib::Mutex::Lock lm (named_selection_lock);
3459 named_selections.insert (named_selections.begin(), named_selection);
3464 NamedSelectionAdded (); /* EMIT SIGNAL */
3468 Session::remove_named_selection (NamedSelection* named_selection)
3470 bool removed = false;
3473 Glib::Mutex::Lock lm (named_selection_lock);
3475 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3477 if (i != named_selections.end()) {
3479 named_selections.erase (i);
3486 NamedSelectionRemoved (); /* EMIT SIGNAL */
3491 Session::reset_native_file_format ()
3493 // jlc - WHY take routelock?
3494 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3495 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3497 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3498 (*i)->reset_write_sources (false);
3503 Session::route_name_unique (string n) const
3505 shared_ptr<RouteList> r = routes.reader ();
3507 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3508 if ((*i)->name() == n) {
3517 Session::cleanup_audio_file_source (AudioFileSource& fs)
3519 return fs.move_to_trash (dead_sound_dir_name);
3523 Session::n_playlists () const
3525 Glib::Mutex::Lock lm (playlist_lock);
3526 return playlists.size();
3530 Session::set_solo_model (SoloModel sm)
3532 if (sm != _solo_model) {
3534 ControlChanged (SoloingModel);
3540 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3542 if (!force && howmany <= _npan_buffers) {
3546 if (_pan_automation_buffer) {
3548 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3549 delete [] _pan_automation_buffer[i];
3552 delete [] _pan_automation_buffer;
3555 _pan_automation_buffer = new pan_t*[howmany];
3557 for (uint32_t i = 0; i < howmany; ++i) {
3558 _pan_automation_buffer[i] = new pan_t[nframes];
3561 _npan_buffers = howmany;
3565 Session::freeze (InterThreadInfo& itt)
3567 shared_ptr<RouteList> r = routes.reader ();
3569 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3573 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3574 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3585 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3586 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3590 AudioFileSource* fsource;
3592 char buf[PATH_MAX+1];
3595 jack_nframes_t position;
3596 jack_nframes_t this_chunk;
3597 jack_nframes_t to_do;
3598 vector<Sample*> buffers;
3601 // any bigger than this seems to cause stack overflows in called functions
3602 const jack_nframes_t chunk_size = (128 * 1024)/4;
3604 g_atomic_int_set (&processing_prohibited, 1);
3606 /* call tree *MUST* hold route_lock */
3608 if ((playlist = track.diskstream().playlist()) == 0) {
3612 /* external redirects will be a problem */
3614 if (track.has_external_redirects()) {
3618 nchans = track.audio_diskstream().n_channels();
3620 dir = discover_best_sound_dir ();
3622 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3624 for (x = 0; x < 99999; ++x) {
3625 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3626 if (access (buf, F_OK) != 0) {
3632 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3637 fsource = new SndFileSource (buf,
3638 Config->get_native_file_data_format(),
3639 Config->get_native_file_header_format(),
3644 catch (failed_constructor& err) {
3645 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3649 srcs.push_back(fsource);
3652 /* XXX need to flush all redirects */
3657 /* create a set of reasonably-sized buffers */
3659 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3661 #ifdef NO_POSIX_MEMALIGN
3662 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3664 posix_memalign((void **)&b,16,chunk_size * 4);
3666 buffers.push_back (b);
3669 workbuf = new char[chunk_size * 4];
3671 while (to_do && !itt.cancel) {
3673 this_chunk = min (to_do, chunk_size);
3675 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3680 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3681 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3684 if (afs->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3690 start += this_chunk;
3691 to_do -= this_chunk;
3693 itt.progress = (float) (1.0 - ((double) to_do / len));
3702 xnow = localtime (&now);
3704 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3705 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3707 afs->update_header (position, *xnow, now);
3711 /* build peakfile for new source */
3713 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3714 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3716 afs->build_peaks ();
3725 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3726 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3728 afs->mark_for_remove ();
3734 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3742 g_atomic_int_set (&processing_prohibited, 0);
3750 Session::get_silent_buffers (uint32_t howmany)
3752 for (uint32_t i = 0; i < howmany; ++i) {
3753 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3755 return _silent_buffers;
3759 Session::ntracks () const
3762 shared_ptr<RouteList> r = routes.reader ();
3764 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3765 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3774 Session::nbusses () const
3777 shared_ptr<RouteList> r = routes.reader ();
3779 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3780 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3789 Session::set_layer_model (LayerModel lm)
3791 if (lm != layer_model) {
3794 ControlChanged (LayeringModel);
3799 Session::set_xfade_model (CrossfadeModel xm)
3801 if (xm != xfade_model) {
3804 ControlChanged (CrossfadingModel);