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);
1018 Session::auto_punch_end_changed (Location* location)
1020 jack_nframes_t when_to_stop = location->end();
1021 // when_to_stop += _worst_output_latency + _worst_input_latency;
1022 replace_event (Event::PunchOut, when_to_stop);
1026 Session::auto_punch_changed (Location* location)
1028 jack_nframes_t when_to_stop = location->end();
1030 replace_event (Event::PunchIn, location->start());
1031 //when_to_stop += _worst_output_latency + _worst_input_latency;
1032 replace_event (Event::PunchOut, when_to_stop);
1036 Session::auto_loop_changed (Location* location)
1038 replace_event (Event::AutoLoop, location->end(), location->start());
1040 if (transport_rolling() && get_auto_loop()) {
1042 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1044 if (_transport_frame > location->end()) {
1045 // relocate to beginning of loop
1046 clear_events (Event::LocateRoll);
1048 request_locate (location->start(), true);
1051 else if (seamless_loop && !loop_changing) {
1053 // schedule a locate-roll to refill the diskstreams at the
1054 // previous loop end
1055 loop_changing = true;
1057 if (location->end() > last_loopend) {
1058 clear_events (Event::LocateRoll);
1059 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1066 last_loopend = location->end();
1071 Session::set_auto_punch_location (Location* location)
1075 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1076 auto_punch_start_changed_connection.disconnect();
1077 auto_punch_end_changed_connection.disconnect();
1078 auto_punch_changed_connection.disconnect();
1079 existing->set_auto_punch (false, this);
1080 remove_event (existing->start(), Event::PunchIn);
1081 clear_events (Event::PunchOut);
1082 auto_punch_location_changed (0);
1087 if (location == 0) {
1091 if (location->end() <= location->start()) {
1092 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1096 auto_punch_start_changed_connection.disconnect();
1097 auto_punch_end_changed_connection.disconnect();
1098 auto_punch_changed_connection.disconnect();
1100 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1101 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1102 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1104 location->set_auto_punch (true, this);
1105 auto_punch_location_changed (location);
1109 Session::set_punch_in (bool yn)
1111 if (punch_in == yn) {
1117 if ((location = _locations.auto_punch_location()) != 0) {
1118 if ((punch_in = yn) == true) {
1119 replace_event (Event::PunchIn, location->start());
1121 remove_event (location->start(), Event::PunchIn);
1126 ControlChanged (PunchIn); /* EMIT SIGNAL */
1130 Session::set_punch_out (bool yn)
1132 if (punch_out == yn) {
1138 if ((location = _locations.auto_punch_location()) != 0) {
1139 if ((punch_out = yn) == true) {
1140 replace_event (Event::PunchOut, location->end());
1142 clear_events (Event::PunchOut);
1147 ControlChanged (PunchOut); /* EMIT SIGNAL */
1151 Session::set_auto_loop_location (Location* location)
1155 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1156 auto_loop_start_changed_connection.disconnect();
1157 auto_loop_end_changed_connection.disconnect();
1158 auto_loop_changed_connection.disconnect();
1159 existing->set_auto_loop (false, this);
1160 remove_event (existing->end(), Event::AutoLoop);
1161 auto_loop_location_changed (0);
1166 if (location == 0) {
1170 if (location->end() <= location->start()) {
1171 error << _("Session: you can't use a mark for auto loop") << endmsg;
1175 last_loopend = location->end();
1177 auto_loop_start_changed_connection.disconnect();
1178 auto_loop_end_changed_connection.disconnect();
1179 auto_loop_changed_connection.disconnect();
1181 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1182 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1183 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1185 location->set_auto_loop (true, this);
1186 auto_loop_location_changed (location);
1190 Session::locations_added (Location* ignored)
1196 Session::locations_changed ()
1198 _locations.apply (*this, &Session::handle_locations_changed);
1202 Session::handle_locations_changed (Locations::LocationList& locations)
1204 Locations::LocationList::iterator i;
1206 bool set_loop = false;
1207 bool set_punch = false;
1209 for (i = locations.begin(); i != locations.end(); ++i) {
1213 if (location->is_auto_punch()) {
1214 set_auto_punch_location (location);
1217 if (location->is_auto_loop()) {
1218 set_auto_loop_location (location);
1225 set_auto_loop_location (0);
1228 set_auto_punch_location (0);
1235 Session::enable_record ()
1237 /* XXX really atomic compare+swap here */
1238 if (g_atomic_int_get (&_record_status) != Recording) {
1239 g_atomic_int_set (&_record_status, Recording);
1240 _last_record_location = _transport_frame;
1241 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1243 if (Config->get_use_hardware_monitoring() && auto_input) {
1244 /* Even though this can be called from RT context we are using
1245 a non-tentative rwlock here, because the action must occur.
1246 The rarity and short potential lock duration makes this "OK"
1248 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1250 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1251 if ((*i)->record_enabled ()) {
1252 (*i)->monitor_input (true);
1257 RecordStateChanged ();
1262 Session::disable_record (bool rt_context, bool force)
1266 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1268 if (!Config->get_latched_record_enable () || force) {
1269 g_atomic_int_set (&_record_status, Disabled);
1271 if (rs == Recording) {
1272 g_atomic_int_set (&_record_status, Enabled);
1276 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1278 if (Config->get_use_hardware_monitoring() && auto_input) {
1279 /* Even though this can be called from RT context we are using
1280 a non-tentative rwlock here, because the action must occur.
1281 The rarity and short potential lock duration makes this "OK"
1283 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1285 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1286 if ((*i)->record_enabled ()) {
1287 (*i)->monitor_input (false);
1292 RecordStateChanged (); /* emit signal */
1295 remove_pending_capture_state ();
1301 Session::step_back_from_record ()
1303 g_atomic_int_set (&_record_status, Enabled);
1305 if (Config->get_use_hardware_monitoring()) {
1306 /* Even though this can be called from RT context we are using
1307 a non-tentative rwlock here, because the action must occur.
1308 The rarity and short potential lock duration makes this "OK"
1310 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1312 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1313 if (auto_input && (*i)->record_enabled ()) {
1314 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1315 (*i)->monitor_input (false);
1322 Session::maybe_enable_record ()
1324 g_atomic_int_set (&_record_status, Enabled);
1326 /* XXX this save should really happen in another thread. its needed so that
1327 pending capture state can be recovered if we crash.
1330 save_state ("", true);
1332 if (_transport_speed) {
1337 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1338 RecordStateChanged (); /* EMIT SIGNAL */
1345 Session::audible_frame () const
1348 jack_nframes_t offset;
1351 /* the first of these two possible settings for "offset"
1352 mean that the audible frame is stationary until
1353 audio emerges from the latency compensation
1356 the second means that the audible frame is stationary
1357 until audio would emerge from a physical port
1358 in the absence of any plugin latency compensation
1361 offset = _worst_output_latency;
1363 if (offset > current_block_size) {
1364 offset -= current_block_size;
1366 /* XXX is this correct? if we have no external
1367 physical connections and everything is internal
1368 then surely this is zero? still, how
1369 likely is that anyway?
1371 offset = current_block_size;
1374 if (synced_to_jack()) {
1375 tf = _engine.transport_frame();
1377 tf = _transport_frame;
1380 if (_transport_speed == 0) {
1390 if (!non_realtime_work_pending()) {
1394 /* take latency into account */
1403 Session::set_frame_rate (jack_nframes_t frames_per_second)
1405 /** \fn void Session::set_frame_size(jack_nframes_t)
1406 the AudioEngine object that calls this guarantees
1407 that it will not be called while we are also in
1408 ::process(). Its fine to do things that block
1412 _current_frame_rate = frames_per_second;
1413 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1415 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1417 // XXX we need some equivalent to this, somehow
1418 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1422 /* XXX need to reset/reinstantiate all LADSPA plugins */
1426 Session::set_block_size (jack_nframes_t nframes)
1428 /* the AudioEngine guarantees
1429 that it will not be called while we are also in
1430 ::process(). It is therefore fine to do things that block
1435 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1436 vector<Sample*>::iterator i;
1439 current_block_size = nframes;
1441 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1445 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1449 _passthru_buffers.clear ();
1450 _silent_buffers.clear ();
1452 ensure_passthru_buffers (np);
1454 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1458 #ifdef NO_POSIX_MEMALIGN
1459 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1461 posix_memalign((void **)&buf,16,current_block_size * 4);
1465 memset (*i, 0, sizeof (Sample) * current_block_size);
1469 if (_gain_automation_buffer) {
1470 delete [] _gain_automation_buffer;
1472 _gain_automation_buffer = new gain_t[nframes];
1474 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1476 boost::shared_ptr<RouteList> r = routes.reader ();
1478 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1479 (*i)->set_block_size (nframes);
1482 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1483 (*i)->set_block_size (nframes);
1486 set_worst_io_latencies ();
1491 Session::set_default_fade (float steepness, float fade_msecs)
1494 jack_nframes_t fade_frames;
1496 /* Don't allow fade of less 1 frame */
1498 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1505 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1509 default_fade_msecs = fade_msecs;
1510 default_fade_steepness = steepness;
1513 // jlc, WTF is this!
1514 Glib::RWLock::ReaderLock lm (route_lock);
1515 AudioRegion::set_default_fade (steepness, fade_frames);
1520 /* XXX have to do this at some point */
1521 /* foreach region using default fade, reset, then
1522 refill_all_diskstream_buffers ();
1527 struct RouteSorter {
1528 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1529 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1531 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1534 if (r1->fed_by.empty()) {
1535 if (r2->fed_by.empty()) {
1536 /* no ardour-based connections inbound to either route. just use signal order */
1537 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1539 /* r2 has connections, r1 does not; run r1 early */
1543 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1550 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1552 shared_ptr<Route> r2;
1554 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1555 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1559 /* make a copy of the existing list of routes that feed r1 */
1561 set<shared_ptr<Route> > existing = r1->fed_by;
1563 /* for each route that feeds r1, recurse, marking it as feeding
1567 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1570 /* r2 is a route that feeds r1 which somehow feeds base. mark
1571 base as being fed by r2
1574 rbase->fed_by.insert (r2);
1578 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1582 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1586 /* now recurse, so that we can mark base as being fed by
1587 all routes that feed r2
1590 trace_terminal (r2, rbase);
1597 Session::resort_routes ()
1599 /* don't do anything here with signals emitted
1600 by Routes while we are being destroyed.
1603 if (_state_of_the_state & Deletion) {
1610 RCUWriter<RouteList> writer (routes);
1611 shared_ptr<RouteList> r = writer.get_copy ();
1612 resort_routes_using (r);
1613 /* writer goes out of scope and forces update */
1618 Session::resort_routes_using (shared_ptr<RouteList> r)
1620 RouteList::iterator i, j;
1622 for (i = r->begin(); i != r->end(); ++i) {
1624 (*i)->fed_by.clear ();
1626 for (j = r->begin(); j != r->end(); ++j) {
1628 /* although routes can feed themselves, it will
1629 cause an endless recursive descent if we
1630 detect it. so don't bother checking for
1638 if ((*j)->feeds (*i)) {
1639 (*i)->fed_by.insert (*j);
1644 for (i = r->begin(); i != r->end(); ++i) {
1645 trace_terminal (*i, *i);
1652 cerr << "finished route resort\n";
1654 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1655 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1662 shared_ptr<AudioTrack>
1663 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1665 char track_name[32];
1667 uint32_t channels_used = 0;
1669 uint32_t nphysical_in;
1670 uint32_t nphysical_out;
1672 /* count existing audio tracks */
1675 shared_ptr<RouteList> r = routes.reader ();
1677 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1678 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1679 if (!(*i)->hidden()) {
1681 channels_used += (*i)->n_inputs();
1687 /* check for duplicate route names, since we might have pre-existing
1688 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1689 save, close,restart,add new route - first named route is now
1694 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1695 if (route_by_name (track_name) == 0) {
1700 } while (n < (UINT_MAX-1));
1702 if (input_auto_connect & AutoConnectPhysical) {
1703 nphysical_in = n_physical_inputs;
1708 if (output_auto_connect & AutoConnectPhysical) {
1709 nphysical_out = n_physical_outputs;
1715 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1717 if (track->ensure_io (input_channels, output_channels, false, this)) {
1718 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1719 input_channels, output_channels)
1724 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1728 if (input_auto_connect & AutoConnectPhysical) {
1729 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1732 if (port.length() && track->connect_input (track->input (x), port, this)) {
1738 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1742 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1743 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1744 } else if (output_auto_connect & AutoConnectMaster) {
1746 port = _master_out->input (x%_master_out->n_inputs())->name();
1750 if (port.length() && track->connect_output (track->output (x), port, this)) {
1756 vector<string> cports;
1757 uint32_t ni = _control_out->n_inputs();
1759 for (n = 0; n < ni; ++n) {
1760 cports.push_back (_control_out->input(n)->name());
1763 track->set_control_outs (cports);
1766 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1770 track->set_remote_control_id (ntracks());
1774 catch (failed_constructor &err) {
1775 error << _("Session: could not create new audio track.") << endmsg;
1776 return shared_ptr<AudioTrack> ((AudioTrack*) 0);
1781 Session::new_audio_route (int input_channels, int output_channels)
1787 /* count existing audio busses */
1790 shared_ptr<RouteList> r = routes.reader ();
1792 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1793 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1794 if (!(*i)->hidden()) {
1802 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1803 if (route_by_name (bus_name) == 0) {
1808 } while (n < (UINT_MAX-1));
1811 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1813 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1814 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1815 input_channels, output_channels)
1819 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1823 if (input_auto_connect & AutoConnectPhysical) {
1824 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1827 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1832 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1836 if (output_auto_connect & AutoConnectPhysical) {
1837 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1838 } else if (output_auto_connect & AutoConnectMaster) {
1840 port = _master_out->input (x%_master_out->n_inputs())->name();
1844 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1850 vector<string> cports;
1851 uint32_t ni = _control_out->n_inputs();
1853 for (uint32_t n = 0; n < ni; ++n) {
1854 cports.push_back (_control_out->input(n)->name());
1856 bus->set_control_outs (cports);
1863 catch (failed_constructor &err) {
1864 error << _("Session: could not create new audio route.") << endmsg;
1865 return shared_ptr<Route> ((Route*) 0);
1870 Session::add_route (shared_ptr<Route> route)
1873 RCUWriter<RouteList> writer (routes);
1874 shared_ptr<RouteList> r = writer.get_copy ();
1875 r->push_front (route);
1876 resort_routes_using (r);
1879 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1880 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1881 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1882 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1884 if (route->master()) {
1885 _master_out = route;
1888 if (route->control()) {
1889 _control_out = route;
1893 save_state (_current_snapshot_name);
1895 RouteAdded (route); /* EMIT SIGNAL */
1899 Session::add_diskstream (Diskstream* dstream)
1901 /* need to do this in case we're rolling at the time, to prevent false underruns */
1902 dstream->do_refill_with_alloc();
1905 Glib::RWLock::WriterLock lm (diskstream_lock);
1906 diskstreams.push_back (dstream);
1909 /* take a reference to the diskstream, preventing it from
1910 ever being deleted until the session itself goes away,
1911 or chooses to remove it for its own purposes.
1915 dstream->set_block_size (current_block_size);
1917 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1918 /* this will connect to future changes, and check the current length */
1919 diskstream_playlist_changed (dstream);
1921 dstream->prepare ();
1924 save_state (_current_snapshot_name);
1926 DiskstreamAdded (dstream); /* EMIT SIGNAL */
1930 Session::remove_route (shared_ptr<Route> route)
1933 RCUWriter<RouteList> writer (routes);
1934 shared_ptr<RouteList> rs = writer.get_copy ();
1937 /* deleting the master out seems like a dumb
1938 idea, but its more of a UI policy issue
1942 if (route == _master_out) {
1943 _master_out = shared_ptr<Route> ((Route*) 0);
1946 if (route == _control_out) {
1947 _control_out = shared_ptr<Route> ((Route*) 0);
1949 /* cancel control outs for all routes */
1951 vector<string> empty;
1953 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1954 (*r)->set_control_outs (empty);
1958 update_route_solo_state ();
1960 /* writer goes out of scope, forces route list update */
1963 // FIXME: audio specific
1965 AudioDiskstream* ds = 0;
1967 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1968 ds = &at->audio_diskstream();
1974 Glib::RWLock::WriterLock lm (diskstream_lock);
1975 diskstreams.remove (ds);
1981 find_current_end ();
1983 update_latency_compensation (false, false);
1986 /* XXX should we disconnect from the Route's signals ? */
1988 save_state (_current_snapshot_name);
1990 /* all shared ptrs to route should go out of scope here */
1994 Session::route_mute_changed (void* src)
2000 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2002 if (solo_update_disabled) {
2009 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2011 shared_ptr<RouteList> r = routes.reader ();
2013 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2015 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2019 /* don't mess with busses */
2021 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2027 /* don't mess with tracks */
2029 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2034 if ((*i) != route &&
2035 ((*i)->mix_group () == 0 ||
2036 (*i)->mix_group () != route->mix_group () ||
2037 !route->mix_group ()->is_active())) {
2039 if ((*i)->soloed()) {
2041 /* if its already soloed, and solo latching is enabled,
2042 then leave it as it is.
2045 if (_solo_latched) {
2052 solo_update_disabled = true;
2053 (*i)->set_solo (false, src);
2054 solo_update_disabled = false;
2058 bool something_soloed = false;
2059 bool same_thing_soloed = false;
2060 bool signal = false;
2062 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2063 if ((*i)->soloed()) {
2064 something_soloed = true;
2065 if (dynamic_cast<AudioTrack*>((*i).get())) {
2067 same_thing_soloed = true;
2072 same_thing_soloed = true;
2080 if (something_soloed != currently_soloing) {
2082 currently_soloing = something_soloed;
2085 modify_solo_mute (is_track, same_thing_soloed);
2088 SoloActive (currently_soloing);
2095 Session::set_solo_latched (bool yn)
2097 if (yn != _solo_latched) {
2100 ControlChanged (SoloLatch);
2105 Session::update_route_solo_state ()
2108 bool is_track = false;
2109 bool signal = false;
2111 /* caller must hold RouteLock */
2113 /* this is where we actually implement solo by changing
2114 the solo mute setting of each track.
2117 shared_ptr<RouteList> r = routes.reader ();
2119 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2120 if ((*i)->soloed()) {
2122 if (dynamic_cast<AudioTrack*>((*i).get())) {
2129 if (mute != currently_soloing) {
2131 currently_soloing = mute;
2134 if (!is_track && !mute) {
2136 /* nothing is soloed */
2138 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2139 (*i)->set_solo_mute (false);
2149 modify_solo_mute (is_track, mute);
2152 SoloActive (currently_soloing);
2157 Session::modify_solo_mute (bool is_track, bool mute)
2159 shared_ptr<RouteList> r = routes.reader ();
2161 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2165 /* only alter track solo mute */
2167 if (dynamic_cast<AudioTrack*>((*i).get())) {
2168 if ((*i)->soloed()) {
2169 (*i)->set_solo_mute (!mute);
2171 (*i)->set_solo_mute (mute);
2177 /* only alter bus solo mute */
2179 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2181 if ((*i)->soloed()) {
2183 (*i)->set_solo_mute (false);
2187 /* don't mute master or control outs
2188 in response to another bus solo
2191 if ((*i) != _master_out &&
2192 (*i) != _control_out) {
2193 (*i)->set_solo_mute (mute);
2204 Session::catch_up_on_solo ()
2206 /* this is called after set_state() to catch the full solo
2207 state, which can't be correctly determined on a per-route
2208 basis, but needs the global overview that only the session
2211 update_route_solo_state();
2215 Session::route_by_name (string name)
2217 shared_ptr<RouteList> r = routes.reader ();
2219 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2220 if ((*i)->name() == name) {
2225 return shared_ptr<Route> ((Route*) 0);
2229 Session::route_by_remote_id (uint32_t id)
2231 shared_ptr<RouteList> r = routes.reader ();
2233 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2234 if ((*i)->remote_control_id() == id) {
2239 return shared_ptr<Route> ((Route*) 0);
2243 Session::find_current_end ()
2245 if (_state_of_the_state & Loading) {
2249 jack_nframes_t max = get_maximum_extent ();
2251 if (max > end_location->end()) {
2252 end_location->set_end (max);
2254 DurationChanged(); /* EMIT SIGNAL */
2259 Session::get_maximum_extent () const
2261 jack_nframes_t max = 0;
2264 /* Don't take the diskstream lock. Caller must have other ways to
2268 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2269 Playlist* pl = (*i)->playlist();
2270 if ((me = pl->get_maximum_extent()) > max) {
2279 Session::diskstream_by_name (string name)
2281 Glib::RWLock::ReaderLock lm (diskstream_lock);
2283 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2284 if ((*i)->name() == name) {
2293 Session::diskstream_by_id (const PBD::ID& id)
2295 Glib::RWLock::ReaderLock lm (diskstream_lock);
2297 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2298 if ((*i)->id() == id) {
2306 /* AudioRegion management */
2309 Session::new_region_name (string old)
2311 string::size_type last_period;
2313 string::size_type len = old.length() + 64;
2316 if ((last_period = old.find_last_of ('.')) == string::npos) {
2318 /* no period present - add one explicitly */
2321 last_period = old.length() - 1;
2326 number = atoi (old.substr (last_period+1).c_str());
2330 while (number < (UINT_MAX-1)) {
2332 AudioRegionList::const_iterator i;
2337 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2340 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2341 if (i->second->name() == sbuf) {
2346 if (i == audio_regions.end()) {
2351 if (number != (UINT_MAX-1)) {
2355 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2360 Session::region_name (string& result, string base, bool newlevel) const
2367 Glib::Mutex::Lock lm (region_lock);
2369 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2377 /* XXX this is going to be slow. optimize me later */
2382 string::size_type pos;
2384 pos = base.find_last_of ('.');
2386 /* pos may be npos, but then we just use entire base */
2388 subbase = base.substr (0, pos);
2392 bool name_taken = true;
2395 Glib::Mutex::Lock lm (region_lock);
2397 for (int n = 1; n < 5000; ++n) {
2400 snprintf (buf, sizeof (buf), ".%d", n);
2405 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2406 if (i->second->name() == result) {
2419 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2427 Session::add_region (Region* region)
2429 AudioRegion* ar = 0;
2430 AudioRegion* oar = 0;
2434 Glib::Mutex::Lock lm (region_lock);
2436 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2438 AudioRegionList::iterator x;
2440 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2442 oar = dynamic_cast<AudioRegion*> (x->second);
2444 if (ar->region_list_equivalent (*oar)) {
2449 if (x == audio_regions.end()) {
2451 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2453 entry.first = region->id();
2456 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2467 fatal << _("programming error: ")
2468 << X_("unknown region type passed to Session::add_region()")
2475 /* mark dirty because something has changed even if we didn't
2476 add the region to the region list.
2482 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2483 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2484 AudioRegionAdded (ar); /* EMIT SIGNAL */
2489 Session::region_changed (Change what_changed, Region* region)
2491 if (what_changed & Region::HiddenChanged) {
2492 /* relay hidden changes */
2493 RegionHiddenChange (region);
2498 Session::region_renamed (Region* region)
2500 add_region (region);
2504 Session::remove_region (Region* region)
2506 AudioRegionList::iterator i;
2507 AudioRegion* ar = 0;
2508 bool removed = false;
2511 Glib::Mutex::Lock lm (region_lock);
2513 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2514 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2515 audio_regions.erase (i);
2521 fatal << _("programming error: ")
2522 << X_("unknown region type passed to Session::remove_region()")
2528 /* mark dirty because something has changed even if we didn't
2529 remove the region from the region list.
2535 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2540 Session::find_whole_file_parent (AudioRegion& child)
2542 AudioRegionList::iterator i;
2543 AudioRegion* region;
2544 Glib::Mutex::Lock lm (region_lock);
2546 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2550 if (region->whole_file()) {
2552 if (child.source_equivalent (*region)) {
2562 Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
2564 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2565 (*i)->get_region_list_equivalent_regions (region, result);
2569 Session::destroy_region (Region* region)
2571 AudioRegion* aregion;
2573 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2577 if (aregion->playlist()) {
2578 aregion->playlist()->destroy_region (region);
2581 vector<Source*> srcs;
2583 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2584 srcs.push_back (&aregion->source (n));
2587 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2589 if ((*i)->use_cnt() == 0) {
2590 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2592 (afs)->mark_for_remove ();
2602 Session::destroy_regions (list<Region*> regions)
2604 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2605 destroy_region (*i);
2611 Session::remove_last_capture ()
2615 Glib::RWLock::ReaderLock lm (diskstream_lock);
2617 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2618 list<Region*>& l = (*i)->last_capture_regions();
2621 r.insert (r.end(), l.begin(), l.end());
2626 destroy_regions (r);
2631 Session::remove_region_from_region_list (Region& r)
2637 /* Source Management */
2640 Session::add_audio_source (AudioSource* source)
2642 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2645 Glib::Mutex::Lock lm (audio_source_lock);
2646 entry.first = source->id();
2647 entry.second = source;
2648 audio_sources.insert (entry);
2651 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2654 SourceAdded (source); /* EMIT SIGNAL */
2658 Session::remove_source (Source* source)
2660 AudioSourceList::iterator i;
2663 Glib::Mutex::Lock lm (audio_source_lock);
2665 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2666 audio_sources.erase (i);
2670 if (!_state_of_the_state & InCleanup) {
2672 /* save state so we don't end up with a session file
2673 referring to non-existent sources.
2676 save_state (_current_snapshot_name);
2679 SourceRemoved(source); /* EMIT SIGNAL */
2683 Session::source_by_id (const PBD::ID& id)
2685 Glib::Mutex::Lock lm (audio_source_lock);
2686 AudioSourceList::iterator i;
2689 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2693 /* XXX search MIDI or other searches here */
2699 Session::peak_path_from_audio_path (string audio_path)
2701 /* XXX hardly bombproof! fix me */
2705 res = Glib::path_get_dirname (audio_path);
2706 res = Glib::path_get_dirname (res);
2708 res += peak_dir_name;
2710 res += PBD::basename_nosuffix (audio_path);
2717 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2720 string old_basename = PBD::basename_nosuffix (oldname);
2721 string new_legalized = legalize_for_path (newname);
2723 /* note: we know (or assume) the old path is already valid */
2727 /* destructive file sources have a name of the form:
2729 /path/to/Tnnnn-NAME(%[LR])?.wav
2731 the task here is to replace NAME with the new name.
2734 /* find last slash */
2738 string::size_type slash;
2739 string::size_type dash;
2741 if ((slash = path.find_last_of ('/')) == string::npos) {
2745 dir = path.substr (0, slash+1);
2747 /* '-' is not a legal character for the NAME part of the path */
2749 if ((dash = path.find_last_of ('-')) == string::npos) {
2753 prefix = path.substr (slash+1, dash-(slash+1));
2758 path += new_legalized;
2759 path += ".wav"; /* XXX gag me with a spoon */
2763 /* non-destructive file sources have a name of the form:
2765 /path/to/NAME-nnnnn(%[LR])?.wav
2767 the task here is to replace NAME with the new name.
2772 string::size_type slash;
2773 string::size_type dash;
2774 string::size_type postfix;
2776 /* find last slash */
2778 if ((slash = path.find_last_of ('/')) == string::npos) {
2782 dir = path.substr (0, slash+1);
2784 /* '-' is not a legal character for the NAME part of the path */
2786 if ((dash = path.find_last_of ('-')) == string::npos) {
2790 suffix = path.substr (dash+1);
2792 // Suffix is now everything after the dash. Now we need to eliminate
2793 // the nnnnn part, which is done by either finding a '%' or a '.'
2795 postfix = suffix.find_last_of ("%");
2796 if (postfix == string::npos) {
2797 postfix = suffix.find_last_of ('.');
2800 if (postfix != string::npos) {
2801 suffix = suffix.substr (postfix);
2803 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2807 const uint32_t limit = 10000;
2808 char buf[PATH_MAX+1];
2810 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2812 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2814 if (access (buf, F_OK) != 0) {
2822 error << "FATAL ERROR! Could not find a " << endl;
2831 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2835 char buf[PATH_MAX+1];
2836 const uint32_t limit = 10000;
2840 legalized = legalize_for_path (name);
2842 /* find a "version" of the file name that doesn't exist in
2843 any of the possible directories.
2846 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2848 vector<space_and_path>::iterator i;
2849 uint32_t existing = 0;
2851 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2856 spath += tape_dir_name;
2858 spath += sound_dir_name;
2863 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2864 } else if (nchan == 2) {
2866 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2868 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2870 } else if (nchan < 26) {
2871 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2873 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2881 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2882 } else if (nchan == 2) {
2884 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2886 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2888 } else if (nchan < 26) {
2889 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2891 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2895 if (access (buf, F_OK) == 0) {
2900 if (existing == 0) {
2905 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2906 throw failed_constructor();
2910 /* we now have a unique name for the file, but figure out where to
2917 spath = tape_dir ();
2919 spath = discover_best_sound_dir ();
2922 string::size_type pos = foo.find_last_of ('/');
2924 if (pos == string::npos) {
2927 spath += foo.substr (pos + 1);
2934 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2936 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2938 /* this might throw failed_constructor(), which is OK */
2941 return new DestructiveFileSource (spath,
2942 Config->get_native_file_data_format(),
2943 Config->get_native_file_header_format(),
2946 return new SndFileSource (spath,
2947 Config->get_native_file_data_format(),
2948 Config->get_native_file_header_format(),
2953 /* Playlist management */
2956 Session::playlist_by_name (string name)
2958 Glib::Mutex::Lock lm (playlist_lock);
2959 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2960 if ((*i)->name() == name) {
2964 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2965 if ((*i)->name() == name) {
2973 Session::add_playlist (Playlist* playlist)
2975 if (playlist->hidden()) {
2980 Glib::Mutex::Lock lm (playlist_lock);
2981 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2982 playlists.insert (playlists.begin(), playlist);
2984 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2985 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
2991 PlaylistAdded (playlist); /* EMIT SIGNAL */
2995 Session::track_playlist (Playlist* pl, bool inuse)
2997 PlaylistList::iterator x;
3000 Glib::Mutex::Lock lm (playlist_lock);
3003 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3005 unused_playlists.insert (pl);
3007 if ((x = playlists.find (pl)) != playlists.end()) {
3008 playlists.erase (x);
3013 //cerr << "shifting playlist to used: " << pl->name() << endl;
3015 playlists.insert (pl);
3017 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3018 unused_playlists.erase (x);
3025 Session::remove_playlist (Playlist* playlist)
3027 if (_state_of_the_state & Deletion) {
3032 Glib::Mutex::Lock lm (playlist_lock);
3033 // cerr << "removing playlist: " << playlist->name() << endl;
3035 PlaylistList::iterator i;
3037 i = find (playlists.begin(), playlists.end(), playlist);
3039 if (i != playlists.end()) {
3040 playlists.erase (i);
3043 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3044 if (i != unused_playlists.end()) {
3045 unused_playlists.erase (i);
3052 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3056 Session::set_audition (AudioRegion* r)
3058 pending_audition_region = r;
3059 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3060 schedule_butler_transport_work ();
3064 Session::non_realtime_set_audition ()
3066 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3067 auditioner->audition_current_playlist ();
3068 } else if (pending_audition_region) {
3069 auditioner->audition_region (*pending_audition_region);
3071 pending_audition_region = 0;
3072 AuditionActive (true); /* EMIT SIGNAL */
3076 Session::audition_playlist ()
3078 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3079 ev->set_ptr ((void*) 0xfeedface);
3084 Session::audition_region (Region& r)
3086 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
3088 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3095 Session::cancel_audition ()
3097 if (auditioner->active()) {
3098 auditioner->cancel_audition ();
3099 AuditionActive (false); /* EMIT SIGNAL */
3104 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3106 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3110 Session::remove_empty_sounds ()
3113 PathScanner scanner;
3118 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3120 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3122 if (AudioFileSource::is_empty (*(*i))) {
3124 unlink ((*i)->c_str());
3126 string peak_path = peak_path_from_audio_path (**i);
3127 unlink (peak_path.c_str());
3133 delete possible_audiofiles;
3137 Session::is_auditioning () const
3139 /* can be called before we have an auditioner object */
3141 return auditioner->active();
3148 Session::set_all_solo (bool yn)
3150 shared_ptr<RouteList> r = routes.reader ();
3152 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3153 if (!(*i)->hidden()) {
3154 (*i)->set_solo (yn, this);
3162 Session::set_all_mute (bool yn)
3164 shared_ptr<RouteList> r = routes.reader ();
3166 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3167 if (!(*i)->hidden()) {
3168 (*i)->set_mute (yn, this);
3176 Session::n_diskstreams () const
3178 Glib::RWLock::ReaderLock lm (diskstream_lock);
3181 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3182 if (!(*i)->hidden()) {
3190 Session::graph_reordered ()
3192 /* don't do this stuff if we are setting up connections
3193 from a set_state() call.
3196 if (_state_of_the_state & InitialConnecting) {
3200 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3204 /* force all diskstreams to update their capture offset values to
3205 reflect any changes in latencies within the graph.
3208 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3209 (*i)->set_capture_offset ();
3214 Session::record_disenable_all ()
3216 record_enable_change_all (false);
3220 Session::record_enable_all ()
3222 record_enable_change_all (true);
3226 Session::record_enable_change_all (bool yn)
3228 shared_ptr<RouteList> r = routes.reader ();
3230 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3233 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3234 at->set_record_enable (yn, this);
3238 /* since we don't keep rec-enable state, don't mark session dirty */
3242 Session::add_redirect (Redirect* redirect)
3246 PortInsert* port_insert;
3247 PluginInsert* plugin_insert;
3249 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3250 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3251 _port_inserts.insert (_port_inserts.begin(), port_insert);
3252 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3253 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3255 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3258 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3259 _sends.insert (_sends.begin(), send);
3261 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3265 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3271 Session::remove_redirect (Redirect* redirect)
3275 PortInsert* port_insert;
3276 PluginInsert* plugin_insert;
3278 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3279 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3280 _port_inserts.remove (port_insert);
3281 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3282 _plugin_inserts.remove (plugin_insert);
3284 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3287 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3288 _sends.remove (send);
3290 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3298 Session::available_capture_duration ()
3300 const double scale = 4096.0 / sizeof (Sample);
3302 if (_total_free_4k_blocks * scale > (double) max_frames) {
3306 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3310 Session::add_connection (ARDOUR::Connection* connection)
3313 Glib::Mutex::Lock guard (connection_lock);
3314 _connections.push_back (connection);
3317 ConnectionAdded (connection); /* EMIT SIGNAL */
3323 Session::remove_connection (ARDOUR::Connection* connection)
3325 bool removed = false;
3328 Glib::Mutex::Lock guard (connection_lock);
3329 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3331 if (i != _connections.end()) {
3332 _connections.erase (i);
3338 ConnectionRemoved (connection); /* EMIT SIGNAL */
3344 ARDOUR::Connection *
3345 Session::connection_by_name (string name) const
3347 Glib::Mutex::Lock lm (connection_lock);
3349 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3350 if ((*i)->name() == name) {
3359 Session::set_edit_mode (EditMode mode)
3364 Glib::Mutex::Lock lm (playlist_lock);
3366 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3367 (*i)->set_edit_mode (mode);
3372 ControlChanged (EditingMode); /* EMIT SIGNAL */
3376 Session::tempo_map_changed (Change ignored)
3383 Session::ensure_passthru_buffers (uint32_t howmany)
3385 while (howmany > _passthru_buffers.size()) {
3387 #ifdef NO_POSIX_MEMALIGN
3388 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3390 posix_memalign((void **)&p,16,current_block_size * 4);
3392 _passthru_buffers.push_back (p);
3396 #ifdef NO_POSIX_MEMALIGN
3397 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3399 posix_memalign((void **)&p,16,current_block_size * 4);
3401 memset (p, 0, sizeof (Sample) * current_block_size);
3402 _silent_buffers.push_back (p);
3406 #ifdef NO_POSIX_MEMALIGN
3407 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3409 posix_memalign((void **)&p,16,current_block_size * 4);
3411 memset (p, 0, sizeof (Sample) * current_block_size);
3412 _send_buffers.push_back (p);
3415 allocate_pan_automation_buffers (current_block_size, howmany, false);
3419 Session::next_send_name ()
3422 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3427 Session::next_insert_name ()
3430 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3434 /* Named Selection management */
3437 Session::named_selection_by_name (string name)
3439 Glib::Mutex::Lock lm (named_selection_lock);
3440 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3441 if ((*i)->name == name) {
3449 Session::add_named_selection (NamedSelection* named_selection)
3452 Glib::Mutex::Lock lm (named_selection_lock);
3453 named_selections.insert (named_selections.begin(), named_selection);
3458 NamedSelectionAdded (); /* EMIT SIGNAL */
3462 Session::remove_named_selection (NamedSelection* named_selection)
3464 bool removed = false;
3467 Glib::Mutex::Lock lm (named_selection_lock);
3469 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3471 if (i != named_selections.end()) {
3473 named_selections.erase (i);
3480 NamedSelectionRemoved (); /* EMIT SIGNAL */
3485 Session::reset_native_file_format ()
3487 // jlc - WHY take routelock?
3488 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3489 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3491 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3492 (*i)->reset_write_sources (false);
3497 Session::route_name_unique (string n) const
3499 shared_ptr<RouteList> r = routes.reader ();
3501 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3502 if ((*i)->name() == n) {
3511 Session::cleanup_audio_file_source (AudioFileSource& fs)
3513 return fs.move_to_trash (dead_sound_dir_name);
3517 Session::n_playlists () const
3519 Glib::Mutex::Lock lm (playlist_lock);
3520 return playlists.size();
3524 Session::set_solo_model (SoloModel sm)
3526 if (sm != _solo_model) {
3528 ControlChanged (SoloingModel);
3534 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3536 if (!force && howmany <= _npan_buffers) {
3540 if (_pan_automation_buffer) {
3542 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3543 delete [] _pan_automation_buffer[i];
3546 delete [] _pan_automation_buffer;
3549 _pan_automation_buffer = new pan_t*[howmany];
3551 for (uint32_t i = 0; i < howmany; ++i) {
3552 _pan_automation_buffer[i] = new pan_t[nframes];
3555 _npan_buffers = howmany;
3559 Session::freeze (InterThreadInfo& itt)
3561 shared_ptr<RouteList> r = routes.reader ();
3563 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3567 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3568 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3579 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3580 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3584 AudioFileSource* fsource;
3586 char buf[PATH_MAX+1];
3589 jack_nframes_t position;
3590 jack_nframes_t this_chunk;
3591 jack_nframes_t to_do;
3592 vector<Sample*> buffers;
3595 // any bigger than this seems to cause stack overflows in called functions
3596 const jack_nframes_t chunk_size = (128 * 1024)/4;
3598 g_atomic_int_set (&processing_prohibited, 1);
3600 /* call tree *MUST* hold route_lock */
3602 if ((playlist = track.diskstream().playlist()) == 0) {
3606 /* external redirects will be a problem */
3608 if (track.has_external_redirects()) {
3612 nchans = track.audio_diskstream().n_channels();
3614 dir = discover_best_sound_dir ();
3616 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3618 for (x = 0; x < 99999; ++x) {
3619 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3620 if (access (buf, F_OK) != 0) {
3626 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3631 fsource = new SndFileSource (buf,
3632 Config->get_native_file_data_format(),
3633 Config->get_native_file_header_format(),
3638 catch (failed_constructor& err) {
3639 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3643 srcs.push_back(fsource);
3646 /* XXX need to flush all redirects */
3651 /* create a set of reasonably-sized buffers */
3653 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3655 #ifdef NO_POSIX_MEMALIGN
3656 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3658 posix_memalign((void **)&b,16,chunk_size * 4);
3660 buffers.push_back (b);
3663 workbuf = new char[chunk_size * 4];
3665 while (to_do && !itt.cancel) {
3667 this_chunk = min (to_do, chunk_size);
3669 if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
3674 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3675 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3678 if (afs->write (buffers[n], this_chunk, workbuf) != this_chunk) {
3684 start += this_chunk;
3685 to_do -= this_chunk;
3687 itt.progress = (float) (1.0 - ((double) to_do / len));
3696 xnow = localtime (&now);
3698 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3699 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3701 afs->update_header (position, *xnow, now);
3705 /* build peakfile for new source */
3707 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3708 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3710 afs->build_peaks ();
3719 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3720 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3722 afs->mark_for_remove ();
3728 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3736 g_atomic_int_set (&processing_prohibited, 0);
3744 Session::get_silent_buffers (uint32_t howmany)
3746 for (uint32_t i = 0; i < howmany; ++i) {
3747 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3749 return _silent_buffers;
3753 Session::ntracks () const
3756 shared_ptr<RouteList> r = routes.reader ();
3758 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3759 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3768 Session::nbusses () const
3771 shared_ptr<RouteList> r = routes.reader ();
3773 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3774 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3783 Session::set_layer_model (LayerModel lm)
3785 if (lm != layer_model) {
3788 ControlChanged (LayeringModel);
3793 Session::set_xfade_model (CrossfadeModel xm)
3795 if (xm != xfade_model) {
3798 ControlChanged (CrossfadingModel);