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);
1897 RouteAdded (route); /* EMIT SIGNAL */
1901 Session::add_diskstream (Diskstream* dstream)
1903 /* need to do this in case we're rolling at the time, to prevent false underruns */
1904 dstream->do_refill_with_alloc();
1907 Glib::RWLock::WriterLock lm (diskstream_lock);
1908 diskstreams.push_back (dstream);
1911 /* take a reference to the diskstream, preventing it from
1912 ever being deleted until the session itself goes away,
1913 or chooses to remove it for its own purposes.
1917 dstream->set_block_size (current_block_size);
1919 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1920 /* this will connect to future changes, and check the current length */
1921 diskstream_playlist_changed (dstream);
1923 dstream->prepare ();
1926 save_state (_current_snapshot_name);
1929 DiskstreamAdded (dstream); /* EMIT SIGNAL */
1933 Session::remove_route (shared_ptr<Route> route)
1936 RCUWriter<RouteList> writer (routes);
1937 shared_ptr<RouteList> rs = writer.get_copy ();
1940 /* deleting the master out seems like a dumb
1941 idea, but its more of a UI policy issue
1945 if (route == _master_out) {
1946 _master_out = shared_ptr<Route> ((Route*) 0);
1949 if (route == _control_out) {
1950 _control_out = shared_ptr<Route> ((Route*) 0);
1952 /* cancel control outs for all routes */
1954 vector<string> empty;
1956 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1957 (*r)->set_control_outs (empty);
1961 update_route_solo_state ();
1963 /* writer goes out of scope, forces route list update */
1966 // FIXME: audio specific
1968 AudioDiskstream* ds = 0;
1970 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1971 ds = &at->audio_diskstream();
1977 Glib::RWLock::WriterLock lm (diskstream_lock);
1978 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);
1993 /* all shared ptrs to route should go out of scope here */
1997 Session::route_mute_changed (void* src)
2003 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2005 if (solo_update_disabled) {
2012 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2014 shared_ptr<RouteList> r = routes.reader ();
2016 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2018 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2022 /* don't mess with busses */
2024 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2030 /* don't mess with tracks */
2032 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2037 if ((*i) != route &&
2038 ((*i)->mix_group () == 0 ||
2039 (*i)->mix_group () != route->mix_group () ||
2040 !route->mix_group ()->is_active())) {
2042 if ((*i)->soloed()) {
2044 /* if its already soloed, and solo latching is enabled,
2045 then leave it as it is.
2048 if (_solo_latched) {
2055 solo_update_disabled = true;
2056 (*i)->set_solo (false, src);
2057 solo_update_disabled = false;
2061 bool something_soloed = false;
2062 bool same_thing_soloed = false;
2063 bool signal = false;
2065 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2066 if ((*i)->soloed()) {
2067 something_soloed = true;
2068 if (dynamic_cast<AudioTrack*>((*i).get())) {
2070 same_thing_soloed = true;
2075 same_thing_soloed = true;
2083 if (something_soloed != currently_soloing) {
2085 currently_soloing = something_soloed;
2088 modify_solo_mute (is_track, same_thing_soloed);
2091 SoloActive (currently_soloing);
2098 Session::set_solo_latched (bool yn)
2100 if (yn != _solo_latched) {
2103 ControlChanged (SoloLatch);
2108 Session::update_route_solo_state ()
2111 bool is_track = false;
2112 bool signal = false;
2114 /* caller must hold RouteLock */
2116 /* this is where we actually implement solo by changing
2117 the solo mute setting of each track.
2120 shared_ptr<RouteList> r = routes.reader ();
2122 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2123 if ((*i)->soloed()) {
2125 if (dynamic_cast<AudioTrack*>((*i).get())) {
2132 if (mute != currently_soloing) {
2134 currently_soloing = mute;
2137 if (!is_track && !mute) {
2139 /* nothing is soloed */
2141 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2142 (*i)->set_solo_mute (false);
2152 modify_solo_mute (is_track, mute);
2155 SoloActive (currently_soloing);
2160 Session::modify_solo_mute (bool is_track, bool mute)
2162 shared_ptr<RouteList> r = routes.reader ();
2164 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2168 /* only alter track solo mute */
2170 if (dynamic_cast<AudioTrack*>((*i).get())) {
2171 if ((*i)->soloed()) {
2172 (*i)->set_solo_mute (!mute);
2174 (*i)->set_solo_mute (mute);
2180 /* only alter bus solo mute */
2182 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2184 if ((*i)->soloed()) {
2186 (*i)->set_solo_mute (false);
2190 /* don't mute master or control outs
2191 in response to another bus solo
2194 if ((*i) != _master_out &&
2195 (*i) != _control_out) {
2196 (*i)->set_solo_mute (mute);
2207 Session::catch_up_on_solo ()
2209 /* this is called after set_state() to catch the full solo
2210 state, which can't be correctly determined on a per-route
2211 basis, but needs the global overview that only the session
2214 update_route_solo_state();
2218 Session::route_by_name (string name)
2220 shared_ptr<RouteList> r = routes.reader ();
2222 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2223 if ((*i)->name() == name) {
2228 return shared_ptr<Route> ((Route*) 0);
2232 Session::route_by_remote_id (uint32_t id)
2234 shared_ptr<RouteList> r = routes.reader ();
2236 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2237 if ((*i)->remote_control_id() == id) {
2242 return shared_ptr<Route> ((Route*) 0);
2246 Session::find_current_end ()
2248 if (_state_of_the_state & Loading) {
2252 jack_nframes_t max = get_maximum_extent ();
2254 if (max > end_location->end()) {
2255 end_location->set_end (max);
2257 DurationChanged(); /* EMIT SIGNAL */
2262 Session::get_maximum_extent () const
2264 jack_nframes_t max = 0;
2267 /* Don't take the diskstream lock. Caller must have other ways to
2271 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2272 Playlist* pl = (*i)->playlist();
2273 if ((me = pl->get_maximum_extent()) > max) {
2282 Session::diskstream_by_name (string name)
2284 Glib::RWLock::ReaderLock lm (diskstream_lock);
2286 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2287 if ((*i)->name() == name) {
2296 Session::diskstream_by_id (const PBD::ID& id)
2298 Glib::RWLock::ReaderLock lm (diskstream_lock);
2300 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2301 if ((*i)->id() == id) {
2309 /* AudioRegion management */
2312 Session::new_region_name (string old)
2314 string::size_type last_period;
2316 string::size_type len = old.length() + 64;
2319 if ((last_period = old.find_last_of ('.')) == string::npos) {
2321 /* no period present - add one explicitly */
2324 last_period = old.length() - 1;
2329 number = atoi (old.substr (last_period+1).c_str());
2333 while (number < (UINT_MAX-1)) {
2335 AudioRegionList::const_iterator i;
2340 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2343 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2344 if (i->second->name() == sbuf) {
2349 if (i == audio_regions.end()) {
2354 if (number != (UINT_MAX-1)) {
2358 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2363 Session::region_name (string& result, string base, bool newlevel) const
2370 Glib::Mutex::Lock lm (region_lock);
2372 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2380 /* XXX this is going to be slow. optimize me later */
2385 string::size_type pos;
2387 pos = base.find_last_of ('.');
2389 /* pos may be npos, but then we just use entire base */
2391 subbase = base.substr (0, pos);
2395 bool name_taken = true;
2398 Glib::Mutex::Lock lm (region_lock);
2400 for (int n = 1; n < 5000; ++n) {
2403 snprintf (buf, sizeof (buf), ".%d", n);
2408 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2409 if (i->second->name() == result) {
2422 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2430 Session::add_region (Region* region)
2432 AudioRegion* ar = 0;
2433 AudioRegion* oar = 0;
2437 Glib::Mutex::Lock lm (region_lock);
2439 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2441 AudioRegionList::iterator x;
2443 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2445 oar = dynamic_cast<AudioRegion*> (x->second);
2447 if (ar->region_list_equivalent (*oar)) {
2452 if (x == audio_regions.end()) {
2454 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2456 entry.first = region->id();
2459 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2470 fatal << _("programming error: ")
2471 << X_("unknown region type passed to Session::add_region()")
2478 /* mark dirty because something has changed even if we didn't
2479 add the region to the region list.
2485 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2486 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2487 AudioRegionAdded (ar); /* EMIT SIGNAL */
2492 Session::region_changed (Change what_changed, Region* region)
2494 if (what_changed & Region::HiddenChanged) {
2495 /* relay hidden changes */
2496 RegionHiddenChange (region);
2501 Session::region_renamed (Region* region)
2503 add_region (region);
2507 Session::remove_region (Region* region)
2509 AudioRegionList::iterator i;
2510 AudioRegion* ar = 0;
2511 bool removed = false;
2514 Glib::Mutex::Lock lm (region_lock);
2516 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2517 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2518 audio_regions.erase (i);
2524 fatal << _("programming error: ")
2525 << X_("unknown region type passed to Session::remove_region()")
2531 /* mark dirty because something has changed even if we didn't
2532 remove the region from the region list.
2538 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2543 Session::find_whole_file_parent (AudioRegion& child)
2545 AudioRegionList::iterator i;
2546 AudioRegion* region;
2547 Glib::Mutex::Lock lm (region_lock);
2549 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2553 if (region->whole_file()) {
2555 if (child.source_equivalent (*region)) {
2565 Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
2567 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2568 (*i)->get_region_list_equivalent_regions (region, result);
2572 Session::destroy_region (Region* region)
2574 AudioRegion* aregion;
2576 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2580 if (aregion->playlist()) {
2581 aregion->playlist()->destroy_region (region);
2584 vector<Source*> srcs;
2586 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2587 srcs.push_back (&aregion->source (n));
2590 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2592 if ((*i)->use_cnt() == 0) {
2593 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2595 (afs)->mark_for_remove ();
2605 Session::destroy_regions (list<Region*> regions)
2607 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2608 destroy_region (*i);
2614 Session::remove_last_capture ()
2618 Glib::RWLock::ReaderLock lm (diskstream_lock);
2620 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2621 list<Region*>& l = (*i)->last_capture_regions();
2624 r.insert (r.end(), l.begin(), l.end());
2629 destroy_regions (r);
2634 Session::remove_region_from_region_list (Region& r)
2640 /* Source Management */
2643 Session::add_audio_source (AudioSource* source)
2645 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2648 Glib::Mutex::Lock lm (audio_source_lock);
2649 entry.first = source->id();
2650 entry.second = source;
2651 audio_sources.insert (entry);
2654 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2657 SourceAdded (source); /* EMIT SIGNAL */
2661 Session::remove_source (Source* source)
2663 AudioSourceList::iterator i;
2666 Glib::Mutex::Lock lm (audio_source_lock);
2668 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2669 audio_sources.erase (i);
2673 if (!_state_of_the_state & InCleanup) {
2675 /* save state so we don't end up with a session file
2676 referring to non-existent sources.
2679 save_state (_current_snapshot_name);
2683 SourceRemoved(source); /* EMIT SIGNAL */
2687 Session::source_by_id (const PBD::ID& id)
2689 Glib::Mutex::Lock lm (audio_source_lock);
2690 AudioSourceList::iterator i;
2693 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2697 /* XXX search MIDI or other searches here */
2703 Session::peak_path_from_audio_path (string audio_path)
2705 /* XXX hardly bombproof! fix me */
2709 res = Glib::path_get_dirname (audio_path);
2710 res = Glib::path_get_dirname (res);
2712 res += peak_dir_name;
2714 res += PBD::basename_nosuffix (audio_path);
2721 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2724 string old_basename = PBD::basename_nosuffix (oldname);
2725 string new_legalized = legalize_for_path (newname);
2727 /* note: we know (or assume) the old path is already valid */
2731 /* destructive file sources have a name of the form:
2733 /path/to/Tnnnn-NAME(%[LR])?.wav
2735 the task here is to replace NAME with the new name.
2738 /* find last slash */
2742 string::size_type slash;
2743 string::size_type dash;
2745 if ((slash = path.find_last_of ('/')) == string::npos) {
2749 dir = path.substr (0, slash+1);
2751 /* '-' is not a legal character for the NAME part of the path */
2753 if ((dash = path.find_last_of ('-')) == string::npos) {
2757 prefix = path.substr (slash+1, dash-(slash+1));
2762 path += new_legalized;
2763 path += ".wav"; /* XXX gag me with a spoon */
2767 /* non-destructive file sources have a name of the form:
2769 /path/to/NAME-nnnnn(%[LR])?.wav
2771 the task here is to replace NAME with the new name.
2776 string::size_type slash;
2777 string::size_type dash;
2778 string::size_type postfix;
2780 /* find last slash */
2782 if ((slash = path.find_last_of ('/')) == string::npos) {
2786 dir = path.substr (0, slash+1);
2788 /* '-' is not a legal character for the NAME part of the path */
2790 if ((dash = path.find_last_of ('-')) == string::npos) {
2794 suffix = path.substr (dash+1);
2796 // Suffix is now everything after the dash. Now we need to eliminate
2797 // the nnnnn part, which is done by either finding a '%' or a '.'
2799 postfix = suffix.find_last_of ("%");
2800 if (postfix == string::npos) {
2801 postfix = suffix.find_last_of ('.');
2804 if (postfix != string::npos) {
2805 suffix = suffix.substr (postfix);
2807 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2811 const uint32_t limit = 10000;
2812 char buf[PATH_MAX+1];
2814 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2816 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2818 if (access (buf, F_OK) != 0) {
2826 error << "FATAL ERROR! Could not find a " << endl;
2835 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2839 char buf[PATH_MAX+1];
2840 const uint32_t limit = 10000;
2844 legalized = legalize_for_path (name);
2846 /* find a "version" of the file name that doesn't exist in
2847 any of the possible directories.
2850 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2852 vector<space_and_path>::iterator i;
2853 uint32_t existing = 0;
2855 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2860 spath += tape_dir_name;
2862 spath += sound_dir_name;
2867 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2868 } else if (nchan == 2) {
2870 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2872 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2874 } else if (nchan < 26) {
2875 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2877 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2885 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2886 } else if (nchan == 2) {
2888 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2890 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2892 } else if (nchan < 26) {
2893 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2895 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2899 if (access (buf, F_OK) == 0) {
2904 if (existing == 0) {
2909 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2910 throw failed_constructor();
2914 /* we now have a unique name for the file, but figure out where to
2921 spath = tape_dir ();
2923 spath = discover_best_sound_dir ();
2926 string::size_type pos = foo.find_last_of ('/');
2928 if (pos == string::npos) {
2931 spath += foo.substr (pos + 1);
2938 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2940 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2942 /* this might throw failed_constructor(), which is OK */
2945 return new DestructiveFileSource (spath,
2946 Config->get_native_file_data_format(),
2947 Config->get_native_file_header_format(),
2950 return new SndFileSource (spath,
2951 Config->get_native_file_data_format(),
2952 Config->get_native_file_header_format(),
2957 /* Playlist management */
2960 Session::playlist_by_name (string name)
2962 Glib::Mutex::Lock lm (playlist_lock);
2963 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2964 if ((*i)->name() == name) {
2968 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2969 if ((*i)->name() == name) {
2977 Session::add_playlist (Playlist* playlist)
2979 if (playlist->hidden()) {
2984 Glib::Mutex::Lock lm (playlist_lock);
2985 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2986 playlists.insert (playlists.begin(), playlist);
2988 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2989 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2995 PlaylistAdded (playlist); /* EMIT SIGNAL */
2999 Session::track_playlist (Playlist* pl, bool inuse)
3001 PlaylistList::iterator x;
3004 Glib::Mutex::Lock lm (playlist_lock);
3007 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3009 unused_playlists.insert (pl);
3011 if ((x = playlists.find (pl)) != playlists.end()) {
3012 playlists.erase (x);
3017 //cerr << "shifting playlist to used: " << pl->name() << endl;
3019 playlists.insert (pl);
3021 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3022 unused_playlists.erase (x);
3029 Session::remove_playlist (Playlist* playlist)
3031 if (_state_of_the_state & Deletion) {
3036 Glib::Mutex::Lock lm (playlist_lock);
3037 // cerr << "removing playlist: " << playlist->name() << endl;
3039 PlaylistList::iterator i;
3041 i = find (playlists.begin(), playlists.end(), playlist);
3043 if (i != playlists.end()) {
3044 playlists.erase (i);
3047 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3048 if (i != unused_playlists.end()) {
3049 unused_playlists.erase (i);
3056 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3060 Session::set_audition (AudioRegion* r)
3062 pending_audition_region = r;
3063 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3064 schedule_butler_transport_work ();
3068 Session::non_realtime_set_audition ()
3070 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3071 auditioner->audition_current_playlist ();
3072 } else if (pending_audition_region) {
3073 auditioner->audition_region (*pending_audition_region);
3075 pending_audition_region = 0;
3076 AuditionActive (true); /* EMIT SIGNAL */
3080 Session::audition_playlist ()
3082 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3083 ev->set_ptr ((void*) 0xfeedface);
3088 Session::audition_region (Region& r)
3090 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
3092 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3099 Session::cancel_audition ()
3101 if (auditioner->active()) {
3102 auditioner->cancel_audition ();
3103 AuditionActive (false); /* EMIT SIGNAL */
3108 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3110 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3114 Session::remove_empty_sounds ()
3117 PathScanner scanner;
3122 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3124 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3126 if (AudioFileSource::is_empty (*(*i))) {
3128 unlink ((*i)->c_str());
3130 string peak_path = peak_path_from_audio_path (**i);
3131 unlink (peak_path.c_str());
3137 delete possible_audiofiles;
3141 Session::is_auditioning () const
3143 /* can be called before we have an auditioner object */
3145 return auditioner->active();
3152 Session::set_all_solo (bool yn)
3154 shared_ptr<RouteList> r = routes.reader ();
3156 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3157 if (!(*i)->hidden()) {
3158 (*i)->set_solo (yn, this);
3166 Session::set_all_mute (bool yn)
3168 shared_ptr<RouteList> r = routes.reader ();
3170 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3171 if (!(*i)->hidden()) {
3172 (*i)->set_mute (yn, this);
3180 Session::n_diskstreams () const
3182 Glib::RWLock::ReaderLock lm (diskstream_lock);
3185 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3186 if (!(*i)->hidden()) {
3194 Session::graph_reordered ()
3196 /* don't do this stuff if we are setting up connections
3197 from a set_state() call.
3200 if (_state_of_the_state & InitialConnecting) {
3204 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3208 /* force all diskstreams to update their capture offset values to
3209 reflect any changes in latencies within the graph.
3212 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3213 (*i)->set_capture_offset ();
3218 Session::record_disenable_all ()
3220 record_enable_change_all (false);
3224 Session::record_enable_all ()
3226 record_enable_change_all (true);
3230 Session::record_enable_change_all (bool yn)
3232 shared_ptr<RouteList> r = routes.reader ();
3234 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3237 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3238 at->set_record_enable (yn, this);
3242 /* since we don't keep rec-enable state, don't mark session dirty */
3246 Session::add_redirect (Redirect* redirect)
3250 PortInsert* port_insert;
3251 PluginInsert* plugin_insert;
3253 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3254 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3255 _port_inserts.insert (_port_inserts.begin(), port_insert);
3256 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3257 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3259 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3262 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3263 _sends.insert (_sends.begin(), send);
3265 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3269 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3275 Session::remove_redirect (Redirect* redirect)
3279 PortInsert* port_insert;
3280 PluginInsert* plugin_insert;
3282 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3283 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3284 _port_inserts.remove (port_insert);
3285 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3286 _plugin_inserts.remove (plugin_insert);
3288 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3291 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3292 _sends.remove (send);
3294 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3302 Session::available_capture_duration ()
3304 const double scale = 4096.0 / sizeof (Sample);
3306 if (_total_free_4k_blocks * scale > (double) max_frames) {
3310 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3314 Session::add_connection (ARDOUR::Connection* connection)
3317 Glib::Mutex::Lock guard (connection_lock);
3318 _connections.push_back (connection);
3321 ConnectionAdded (connection); /* EMIT SIGNAL */
3327 Session::remove_connection (ARDOUR::Connection* connection)
3329 bool removed = false;
3332 Glib::Mutex::Lock guard (connection_lock);
3333 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3335 if (i != _connections.end()) {
3336 _connections.erase (i);
3342 ConnectionRemoved (connection); /* EMIT SIGNAL */
3348 ARDOUR::Connection *
3349 Session::connection_by_name (string name) const
3351 Glib::Mutex::Lock lm (connection_lock);
3353 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3354 if ((*i)->name() == name) {
3363 Session::set_edit_mode (EditMode mode)
3368 Glib::Mutex::Lock lm (playlist_lock);
3370 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3371 (*i)->set_edit_mode (mode);
3376 ControlChanged (EditingMode); /* EMIT SIGNAL */
3380 Session::tempo_map_changed (Change ignored)
3387 Session::ensure_passthru_buffers (uint32_t howmany)
3389 while (howmany > _passthru_buffers.size()) {
3391 #ifdef NO_POSIX_MEMALIGN
3392 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3394 posix_memalign((void **)&p,16,current_block_size * 4);
3396 _passthru_buffers.push_back (p);
3400 #ifdef NO_POSIX_MEMALIGN
3401 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3403 posix_memalign((void **)&p,16,current_block_size * 4);
3405 memset (p, 0, sizeof (Sample) * current_block_size);
3406 _silent_buffers.push_back (p);
3410 #ifdef NO_POSIX_MEMALIGN
3411 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3413 posix_memalign((void **)&p,16,current_block_size * 4);
3415 memset (p, 0, sizeof (Sample) * current_block_size);
3416 _send_buffers.push_back (p);
3419 allocate_pan_automation_buffers (current_block_size, howmany, false);
3423 Session::next_send_name ()
3426 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3431 Session::next_insert_name ()
3434 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3438 /* Named Selection management */
3441 Session::named_selection_by_name (string name)
3443 Glib::Mutex::Lock lm (named_selection_lock);
3444 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3445 if ((*i)->name == name) {
3453 Session::add_named_selection (NamedSelection* named_selection)
3456 Glib::Mutex::Lock lm (named_selection_lock);
3457 named_selections.insert (named_selections.begin(), named_selection);
3462 NamedSelectionAdded (); /* EMIT SIGNAL */
3466 Session::remove_named_selection (NamedSelection* named_selection)
3468 bool removed = false;
3471 Glib::Mutex::Lock lm (named_selection_lock);
3473 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3475 if (i != named_selections.end()) {
3477 named_selections.erase (i);
3484 NamedSelectionRemoved (); /* EMIT SIGNAL */
3489 Session::reset_native_file_format ()
3491 // jlc - WHY take routelock?
3492 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3493 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3495 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3496 (*i)->reset_write_sources (false);
3501 Session::route_name_unique (string n) const
3503 shared_ptr<RouteList> r = routes.reader ();
3505 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3506 if ((*i)->name() == n) {
3515 Session::cleanup_audio_file_source (AudioFileSource& fs)
3517 return fs.move_to_trash (dead_sound_dir_name);
3521 Session::n_playlists () const
3523 Glib::Mutex::Lock lm (playlist_lock);
3524 return playlists.size();
3528 Session::set_solo_model (SoloModel sm)
3530 if (sm != _solo_model) {
3532 ControlChanged (SoloingModel);
3538 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3540 if (!force && howmany <= _npan_buffers) {
3544 if (_pan_automation_buffer) {
3546 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3547 delete [] _pan_automation_buffer[i];
3550 delete [] _pan_automation_buffer;
3553 _pan_automation_buffer = new pan_t*[howmany];
3555 for (uint32_t i = 0; i < howmany; ++i) {
3556 _pan_automation_buffer[i] = new pan_t[nframes];
3559 _npan_buffers = howmany;
3563 Session::freeze (InterThreadInfo& itt)
3565 shared_ptr<RouteList> r = routes.reader ();
3567 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3571 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3572 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3583 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3584 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3588 AudioFileSource* fsource;
3590 char buf[PATH_MAX+1];
3593 jack_nframes_t position;
3594 jack_nframes_t this_chunk;
3595 jack_nframes_t to_do;
3596 vector<Sample*> buffers;
3599 // any bigger than this seems to cause stack overflows in called functions
3600 const jack_nframes_t chunk_size = (128 * 1024)/4;
3602 g_atomic_int_set (&processing_prohibited, 1);
3604 /* call tree *MUST* hold route_lock */
3606 if ((playlist = track.diskstream().playlist()) == 0) {
3610 /* external redirects will be a problem */
3612 if (track.has_external_redirects()) {
3616 nchans = track.audio_diskstream().n_channels();
3618 dir = discover_best_sound_dir ();
3620 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3622 for (x = 0; x < 99999; ++x) {
3623 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3624 if (access (buf, F_OK) != 0) {
3630 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3635 fsource = new SndFileSource (buf,
3636 Config->get_native_file_data_format(),
3637 Config->get_native_file_header_format(),
3642 catch (failed_constructor& err) {
3643 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3647 srcs.push_back(fsource);
3650 /* XXX need to flush all redirects */
3655 /* create a set of reasonably-sized buffers */
3657 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3659 #ifdef NO_POSIX_MEMALIGN
3660 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3662 posix_memalign((void **)&b,16,chunk_size * 4);
3664 buffers.push_back (b);
3667 workbuf = new char[chunk_size * 4];
3669 while (to_do && !itt.cancel) {
3671 this_chunk = min (to_do, chunk_size);
3673 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3678 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3679 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3682 if (afs->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3688 start += this_chunk;
3689 to_do -= this_chunk;
3691 itt.progress = (float) (1.0 - ((double) to_do / len));
3700 xnow = localtime (&now);
3702 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3703 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3705 afs->update_header (position, *xnow, now);
3709 /* build peakfile for new source */
3711 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3712 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3714 afs->build_peaks ();
3723 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3724 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3726 afs->mark_for_remove ();
3732 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3740 g_atomic_int_set (&processing_prohibited, 0);
3748 Session::get_silent_buffers (uint32_t howmany)
3750 for (uint32_t i = 0; i < howmany; ++i) {
3751 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3753 return _silent_buffers;
3757 Session::ntracks () const
3760 shared_ptr<RouteList> r = routes.reader ();
3762 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3763 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3772 Session::nbusses () const
3775 shared_ptr<RouteList> r = routes.reader ();
3777 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3778 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3787 Session::set_layer_model (LayerModel lm)
3789 if (lm != layer_model) {
3792 ControlChanged (LayeringModel);
3797 Session::set_xfade_model (CrossfadeModel xm)
3799 if (xm != xfade_model) {
3802 ControlChanged (CrossfadingModel);