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 << " (1)" << 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 << " (2)" << 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 AudioDiskstream::free_working_buffers();
399 #undef TRACK_DESTRUCTION
400 #ifdef TRACK_DESTRUCTION
401 cerr << "delete named selections\n";
402 #endif /* TRACK_DESTRUCTION */
403 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
404 NamedSelectionList::iterator tmp;
413 #ifdef TRACK_DESTRUCTION
414 cerr << "delete playlists\n";
415 #endif /* TRACK_DESTRUCTION */
416 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
417 PlaylistList::iterator tmp;
427 #ifdef TRACK_DESTRUCTION
428 cerr << "delete audio regions\n";
429 #endif /* TRACK_DESTRUCTION */
430 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
431 AudioRegionList::iterator tmp;
441 #ifdef TRACK_DESTRUCTION
442 cerr << "delete diskstreams\n";
443 #endif /* TRACK_DESTRUCTION */
444 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
445 DiskstreamList::iterator tmp;
455 #ifdef TRACK_DESTRUCTION
456 cerr << "delete audio sources\n";
457 #endif /* TRACK_DESTRUCTION */
458 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
459 AudioSourceList::iterator tmp;
469 #ifdef TRACK_DESTRUCTION
470 cerr << "delete mix groups\n";
471 #endif /* TRACK_DESTRUCTION */
472 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
473 list<RouteGroup*>::iterator tmp;
483 #ifdef TRACK_DESTRUCTION
484 cerr << "delete edit groups\n";
485 #endif /* TRACK_DESTRUCTION */
486 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
487 list<RouteGroup*>::iterator tmp;
497 #ifdef TRACK_DESTRUCTION
498 cerr << "delete connections\n";
499 #endif /* TRACK_DESTRUCTION */
500 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
501 ConnectionList::iterator tmp;
511 if (butler_mixdown_buffer) {
512 delete [] butler_mixdown_buffer;
515 if (butler_gain_buffer) {
516 delete [] butler_gain_buffer;
519 Crossfade::set_buffer_size (0);
531 Session::set_worst_io_latencies ()
533 _worst_output_latency = 0;
534 _worst_input_latency = 0;
536 if (!_engine.connected()) {
540 boost::shared_ptr<RouteList> r = routes.reader ();
542 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
543 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
544 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
549 Session::when_engine_running ()
551 string first_physical_output;
553 /* we don't want to run execute this again */
555 first_time_running.disconnect ();
557 set_block_size (_engine.frames_per_cycle());
558 set_frame_rate (_engine.frame_rate());
560 /* every time we reconnect, recompute worst case output latencies */
562 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
564 if (synced_to_jack()) {
565 _engine.transport_stop ();
568 if (Config->get_jack_time_master()) {
569 _engine.transport_locate (_transport_frame);
577 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
579 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
581 /* existing state for Click */
583 if (_click_io->set_state (*child->children().front()) == 0) {
585 _clicking = click_requested;
589 error << _("could not setup Click I/O") << endmsg;
595 /* default state for Click */
597 first_physical_output = _engine.get_nth_physical_output (0);
599 if (first_physical_output.length()) {
600 if (_click_io->add_output_port (first_physical_output, this)) {
601 // relax, even though its an error
603 _clicking = click_requested;
609 catch (failed_constructor& err) {
610 error << _("cannot setup Click I/O") << endmsg;
613 set_worst_io_latencies ();
616 ControlChanged (Clicking); /* EMIT SIGNAL */
619 if (auditioner == 0) {
621 /* we delay creating the auditioner till now because
622 it makes its own connections to ports named
623 in the ARDOUR_RC config file. the engine has
624 to be running for this to work.
628 auditioner.reset (new Auditioner (*this));
631 catch (failed_constructor& err) {
632 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
636 /* Create a set of Connection objects that map
637 to the physical outputs currently available
642 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
644 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
646 Connection* c = new OutputConnection (buf, true);
649 c->add_connection (0, _engine.get_nth_physical_output (np));
654 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
656 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
658 Connection* c = new InputConnection (buf, true);
661 c->add_connection (0, _engine.get_nth_physical_input (np));
668 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
670 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
672 Connection* c = new OutputConnection (buf, true);
676 c->add_connection (0, _engine.get_nth_physical_output (np));
677 c->add_connection (1, _engine.get_nth_physical_output (np+1));
682 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
684 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
686 Connection* c = new InputConnection (buf, true);
690 c->add_connection (0, _engine.get_nth_physical_input (np));
691 c->add_connection (1, _engine.get_nth_physical_input (np+1));
700 /* create master/control ports */
705 /* force the master to ignore any later call to this */
707 if (_master_out->pending_state_node) {
708 _master_out->ports_became_legal();
711 /* no panner resets till we are through */
713 _master_out->defer_pan_reset ();
715 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
716 if (_master_out->add_input_port ("", this)) {
717 error << _("cannot setup master inputs")
723 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
724 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
725 error << _("cannot setup master outputs")
732 _master_out->allow_pan_reset ();
736 Connection* c = new OutputConnection (_("Master Out"), true);
738 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
740 c->add_connection ((int) n, _master_out->input(n)->name());
747 /* catch up on send+insert cnts */
751 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
754 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
755 if (id > insert_cnt) {
763 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
766 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
773 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
775 /* hook us up to the engine */
777 _engine.set_session (this);
782 osc->set_session (*this);
785 _state_of_the_state = Clean;
787 DirtyChanged (); /* EMIT SIGNAL */
791 Session::hookup_io ()
793 /* stop graph reordering notifications from
794 causing resorts, etc.
797 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
799 /* Tell all IO objects to create their ports */
806 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
807 if (_control_out->add_input_port ("", this)) {
808 error << _("cannot setup control inputs")
814 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
815 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
816 error << _("cannot set up master outputs")
824 /* Tell all IO objects to connect themselves together */
826 IO::enable_connecting ();
828 /* Now reset all panners */
830 IO::reset_panners ();
832 /* Anyone who cares about input state, wake up and do something */
834 IOConnectionsComplete (); /* EMIT SIGNAL */
836 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
838 /* now handle the whole enchilada as if it was one
844 /* update mixer solo state */
850 Session::playlist_length_changed (Playlist* pl)
852 /* we can't just increase end_location->end() if pl->get_maximum_extent()
853 if larger. if the playlist used to be the longest playlist,
854 and its now shorter, we have to decrease end_location->end(). hence,
855 we have to iterate over all diskstreams and check the
856 playlists currently in use.
862 Session::diskstream_playlist_changed (Diskstream* dstream)
866 if ((playlist = dstream->playlist()) != 0) {
867 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
870 /* see comment in playlist_length_changed () */
875 Session::record_enabling_legal () const
877 /* this used to be in here, but survey says.... we don't need to restrict it */
878 // if (record_status() == Recording) {
889 Session::set_auto_play (bool yn)
891 if (auto_play != yn) {
894 ControlChanged (AutoPlay);
899 Session::set_auto_return (bool yn)
901 if (auto_return != yn) {
904 ControlChanged (AutoReturn);
909 Session::set_crossfades_active (bool yn)
911 if (crossfades_active != yn) {
912 crossfades_active = yn;
914 ControlChanged (CrossFadesActive);
919 Session::set_do_not_record_plugins (bool yn)
921 if (do_not_record_plugins != yn) {
922 do_not_record_plugins = yn;
924 ControlChanged (RecordingPlugins);
929 Session::set_auto_input (bool yn)
931 if (auto_input != yn) {
934 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
935 /* auto-input only makes a difference if we're rolling */
937 /* Even though this can called from RT context we are using
938 a non-tentative rwlock here, because the action must occur.
939 The rarity and short potential lock duration makes this "OK"
941 Glib::RWLock::ReaderLock dsm (diskstream_lock);
942 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
943 if ((*i)->record_enabled ()) {
944 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
945 (*i)->monitor_input (!auto_input);
951 ControlChanged (AutoInput);
956 Session::reset_input_monitor_state ()
958 if (transport_rolling()) {
959 Glib::RWLock::ReaderLock dsm (diskstream_lock);
960 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
961 if ((*i)->record_enabled ()) {
962 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
963 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
967 Glib::RWLock::ReaderLock dsm (diskstream_lock);
968 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
969 if ((*i)->record_enabled ()) {
970 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
971 (*i)->monitor_input (Config->get_use_hardware_monitoring());
979 Session::set_input_auto_connect (bool yn)
982 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
984 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
990 Session::get_input_auto_connect () const
992 return (input_auto_connect & AutoConnectPhysical);
996 Session::set_output_auto_connect (AutoConnectOption aco)
998 output_auto_connect = aco;
1003 Session::auto_punch_start_changed (Location* location)
1005 replace_event (Event::PunchIn, location->start());
1007 if (get_record_enabled() && get_punch_in()) {
1008 /* capture start has been changed, so save new pending state */
1009 save_state ("", true);
1014 Session::auto_punch_end_changed (Location* location)
1016 jack_nframes_t when_to_stop = location->end();
1017 // when_to_stop += _worst_output_latency + _worst_input_latency;
1018 replace_event (Event::PunchOut, when_to_stop);
1022 Session::auto_punch_changed (Location* location)
1024 jack_nframes_t when_to_stop = location->end();
1026 replace_event (Event::PunchIn, location->start());
1027 //when_to_stop += _worst_output_latency + _worst_input_latency;
1028 replace_event (Event::PunchOut, when_to_stop);
1032 Session::auto_loop_changed (Location* location)
1034 replace_event (Event::AutoLoop, location->end(), location->start());
1036 if (transport_rolling() && get_auto_loop()) {
1038 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1040 if (_transport_frame > location->end()) {
1041 // relocate to beginning of loop
1042 clear_events (Event::LocateRoll);
1044 request_locate (location->start(), true);
1047 else if (seamless_loop && !loop_changing) {
1049 // schedule a locate-roll to refill the diskstreams at the
1050 // previous loop end
1051 loop_changing = true;
1053 if (location->end() > last_loopend) {
1054 clear_events (Event::LocateRoll);
1055 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1062 last_loopend = location->end();
1067 Session::set_auto_punch_location (Location* location)
1071 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1072 auto_punch_start_changed_connection.disconnect();
1073 auto_punch_end_changed_connection.disconnect();
1074 auto_punch_changed_connection.disconnect();
1075 existing->set_auto_punch (false, this);
1076 remove_event (existing->start(), Event::PunchIn);
1077 clear_events (Event::PunchOut);
1078 auto_punch_location_changed (0);
1083 if (location == 0) {
1087 if (location->end() <= location->start()) {
1088 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1092 auto_punch_start_changed_connection.disconnect();
1093 auto_punch_end_changed_connection.disconnect();
1094 auto_punch_changed_connection.disconnect();
1096 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1097 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1098 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1100 location->set_auto_punch (true, this);
1101 auto_punch_location_changed (location);
1105 Session::set_punch_in (bool yn)
1107 if (punch_in == yn) {
1113 if ((location = _locations.auto_punch_location()) != 0) {
1114 if ((punch_in = yn) == true) {
1115 replace_event (Event::PunchIn, location->start());
1117 remove_event (location->start(), Event::PunchIn);
1122 ControlChanged (PunchIn); /* EMIT SIGNAL */
1126 Session::set_punch_out (bool yn)
1128 if (punch_out == yn) {
1134 if ((location = _locations.auto_punch_location()) != 0) {
1135 if ((punch_out = yn) == true) {
1136 replace_event (Event::PunchOut, location->end());
1138 clear_events (Event::PunchOut);
1143 ControlChanged (PunchOut); /* EMIT SIGNAL */
1147 Session::set_auto_loop_location (Location* location)
1151 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1152 auto_loop_start_changed_connection.disconnect();
1153 auto_loop_end_changed_connection.disconnect();
1154 auto_loop_changed_connection.disconnect();
1155 existing->set_auto_loop (false, this);
1156 remove_event (existing->end(), Event::AutoLoop);
1157 auto_loop_location_changed (0);
1162 if (location == 0) {
1166 if (location->end() <= location->start()) {
1167 error << _("Session: you can't use a mark for auto loop") << endmsg;
1171 last_loopend = location->end();
1173 auto_loop_start_changed_connection.disconnect();
1174 auto_loop_end_changed_connection.disconnect();
1175 auto_loop_changed_connection.disconnect();
1177 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1178 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1179 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1181 location->set_auto_loop (true, this);
1182 auto_loop_location_changed (location);
1186 Session::locations_added (Location* ignored)
1192 Session::locations_changed ()
1194 _locations.apply (*this, &Session::handle_locations_changed);
1198 Session::handle_locations_changed (Locations::LocationList& locations)
1200 Locations::LocationList::iterator i;
1202 bool set_loop = false;
1203 bool set_punch = false;
1205 for (i = locations.begin(); i != locations.end(); ++i) {
1209 if (location->is_auto_punch()) {
1210 set_auto_punch_location (location);
1213 if (location->is_auto_loop()) {
1214 set_auto_loop_location (location);
1221 set_auto_loop_location (0);
1224 set_auto_punch_location (0);
1231 Session::enable_record ()
1233 /* XXX really atomic compare+swap here */
1234 if (g_atomic_int_get (&_record_status) != Recording) {
1235 g_atomic_int_set (&_record_status, Recording);
1236 _last_record_location = _transport_frame;
1237 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1239 if (Config->get_use_hardware_monitoring() && auto_input) {
1240 /* Even though this can be called from RT context we are using
1241 a non-tentative rwlock here, because the action must occur.
1242 The rarity and short potential lock duration makes this "OK"
1244 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1246 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1247 if ((*i)->record_enabled ()) {
1248 (*i)->monitor_input (true);
1253 RecordStateChanged ();
1258 Session::disable_record (bool rt_context, bool force)
1262 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1264 if (!Config->get_latched_record_enable () || force) {
1265 g_atomic_int_set (&_record_status, Disabled);
1267 if (rs == Recording) {
1268 g_atomic_int_set (&_record_status, Enabled);
1272 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1274 if (Config->get_use_hardware_monitoring() && auto_input) {
1275 /* Even though this can be called from RT context we are using
1276 a non-tentative rwlock here, because the action must occur.
1277 The rarity and short potential lock duration makes this "OK"
1279 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1281 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1282 if ((*i)->record_enabled ()) {
1283 (*i)->monitor_input (false);
1288 RecordStateChanged (); /* emit signal */
1291 remove_pending_capture_state ();
1297 Session::step_back_from_record ()
1299 g_atomic_int_set (&_record_status, Enabled);
1301 if (Config->get_use_hardware_monitoring()) {
1302 /* Even though this can be called from RT context we are using
1303 a non-tentative rwlock here, because the action must occur.
1304 The rarity and short potential lock duration makes this "OK"
1306 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1308 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1309 if (auto_input && (*i)->record_enabled ()) {
1310 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1311 (*i)->monitor_input (false);
1318 Session::maybe_enable_record ()
1320 g_atomic_int_set (&_record_status, Enabled);
1322 /* XXX this save should really happen in another thread. its needed so that
1323 pending capture state can be recovered if we crash.
1326 save_state ("", true);
1328 if (_transport_speed) {
1333 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1334 RecordStateChanged (); /* EMIT SIGNAL */
1341 Session::audible_frame () const
1344 jack_nframes_t offset;
1347 /* the first of these two possible settings for "offset"
1348 mean that the audible frame is stationary until
1349 audio emerges from the latency compensation
1352 the second means that the audible frame is stationary
1353 until audio would emerge from a physical port
1354 in the absence of any plugin latency compensation
1357 offset = _worst_output_latency;
1359 if (offset > current_block_size) {
1360 offset -= current_block_size;
1362 /* XXX is this correct? if we have no external
1363 physical connections and everything is internal
1364 then surely this is zero? still, how
1365 likely is that anyway?
1367 offset = current_block_size;
1370 if (synced_to_jack()) {
1371 tf = _engine.transport_frame();
1373 tf = _transport_frame;
1376 if (_transport_speed == 0) {
1386 if (!non_realtime_work_pending()) {
1390 /* take latency into account */
1399 Session::set_frame_rate (jack_nframes_t frames_per_second)
1401 /** \fn void Session::set_frame_size(jack_nframes_t)
1402 the AudioEngine object that calls this guarantees
1403 that it will not be called while we are also in
1404 ::process(). Its fine to do things that block
1408 _current_frame_rate = frames_per_second;
1409 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1411 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1413 // XXX we need some equivalent to this, somehow
1414 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1418 /* XXX need to reset/reinstantiate all LADSPA plugins */
1422 Session::set_block_size (jack_nframes_t nframes)
1424 /* the AudioEngine guarantees
1425 that it will not be called while we are also in
1426 ::process(). It is therefore fine to do things that block
1431 Glib::RWLock::ReaderLock dsm (diskstream_lock);
1432 vector<Sample*>::iterator i;
1435 current_block_size = nframes;
1437 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1441 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1445 _passthru_buffers.clear ();
1446 _silent_buffers.clear ();
1448 ensure_passthru_buffers (np);
1450 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1454 #ifdef NO_POSIX_MEMALIGN
1455 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1457 posix_memalign((void **)&buf,16,current_block_size * 4);
1461 memset (*i, 0, sizeof (Sample) * current_block_size);
1465 if (_gain_automation_buffer) {
1466 delete [] _gain_automation_buffer;
1468 _gain_automation_buffer = new gain_t[nframes];
1470 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1472 boost::shared_ptr<RouteList> r = routes.reader ();
1474 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1475 (*i)->set_block_size (nframes);
1478 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1479 (*i)->set_block_size (nframes);
1482 set_worst_io_latencies ();
1487 Session::set_default_fade (float steepness, float fade_msecs)
1490 jack_nframes_t fade_frames;
1492 /* Don't allow fade of less 1 frame */
1494 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1501 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1505 default_fade_msecs = fade_msecs;
1506 default_fade_steepness = steepness;
1509 // jlc, WTF is this!
1510 Glib::RWLock::ReaderLock lm (route_lock);
1511 AudioRegion::set_default_fade (steepness, fade_frames);
1516 /* XXX have to do this at some point */
1517 /* foreach region using default fade, reset, then
1518 refill_all_diskstream_buffers ();
1523 struct RouteSorter {
1524 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1525 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1527 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1530 if (r1->fed_by.empty()) {
1531 if (r2->fed_by.empty()) {
1532 /* no ardour-based connections inbound to either route. just use signal order */
1533 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1535 /* r2 has connections, r1 does not; run r1 early */
1539 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1546 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1548 shared_ptr<Route> r2;
1550 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1551 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1555 /* make a copy of the existing list of routes that feed r1 */
1557 set<shared_ptr<Route> > existing = r1->fed_by;
1559 /* for each route that feeds r1, recurse, marking it as feeding
1563 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1566 /* r2 is a route that feeds r1 which somehow feeds base. mark
1567 base as being fed by r2
1570 rbase->fed_by.insert (r2);
1574 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1578 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1582 /* now recurse, so that we can mark base as being fed by
1583 all routes that feed r2
1586 trace_terminal (r2, rbase);
1593 Session::resort_routes ()
1595 /* don't do anything here with signals emitted
1596 by Routes while we are being destroyed.
1599 if (_state_of_the_state & Deletion) {
1606 RCUWriter<RouteList> writer (routes);
1607 shared_ptr<RouteList> r = writer.get_copy ();
1608 resort_routes_using (r);
1609 /* writer goes out of scope and forces update */
1614 Session::resort_routes_using (shared_ptr<RouteList> r)
1616 RouteList::iterator i, j;
1618 for (i = r->begin(); i != r->end(); ++i) {
1620 (*i)->fed_by.clear ();
1622 for (j = r->begin(); j != r->end(); ++j) {
1624 /* although routes can feed themselves, it will
1625 cause an endless recursive descent if we
1626 detect it. so don't bother checking for
1634 if ((*j)->feeds (*i)) {
1635 (*i)->fed_by.insert (*j);
1640 for (i = r->begin(); i != r->end(); ++i) {
1641 trace_terminal (*i, *i);
1648 cerr << "finished route resort\n";
1650 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1651 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1658 shared_ptr<AudioTrack>
1659 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
1661 char track_name[32];
1663 uint32_t channels_used = 0;
1665 uint32_t nphysical_in;
1666 uint32_t nphysical_out;
1668 /* count existing audio tracks */
1671 shared_ptr<RouteList> r = routes.reader ();
1673 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1674 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1675 if (!(*i)->hidden()) {
1677 channels_used += (*i)->n_inputs();
1683 /* check for duplicate route names, since we might have pre-existing
1684 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1685 save, close,restart,add new route - first named route is now
1690 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, n+1);
1691 if (route_by_name (track_name) == 0) {
1696 } while (n < (UINT_MAX-1));
1698 if (input_auto_connect & AutoConnectPhysical) {
1699 nphysical_in = n_physical_inputs;
1704 if (output_auto_connect & AutoConnectPhysical) {
1705 nphysical_out = n_physical_outputs;
1711 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1713 if (track->ensure_io (input_channels, output_channels, false, this)) {
1714 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1715 input_channels, output_channels)
1720 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1724 if (input_auto_connect & AutoConnectPhysical) {
1725 port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
1728 if (port.length() && track->connect_input (track->input (x), port, this)) {
1734 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1738 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1739 port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
1740 } else if (output_auto_connect & AutoConnectMaster) {
1742 port = _master_out->input (x%_master_out->n_inputs())->name();
1746 if (port.length() && track->connect_output (track->output (x), port, this)) {
1752 vector<string> cports;
1753 uint32_t ni = _control_out->n_inputs();
1755 for (n = 0; n < ni; ++n) {
1756 cports.push_back (_control_out->input(n)->name());
1759 track->set_control_outs (cports);
1762 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1766 track->set_remote_control_id (ntracks());
1770 catch (failed_constructor &err) {
1771 error << _("Session: could not create new audio track.") << endmsg;
1772 return shared_ptr<AudioTrack> ((AudioTrack*) 0);
1777 Session::new_audio_route (int input_channels, int output_channels)
1783 /* count existing audio busses */
1786 shared_ptr<RouteList> r = routes.reader ();
1788 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1789 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1790 if (!(*i)->hidden()) {
1798 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
1799 if (route_by_name (bus_name) == 0) {
1804 } while (n < (UINT_MAX-1));
1807 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1809 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1810 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1811 input_channels, output_channels)
1815 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1819 if (input_auto_connect & AutoConnectPhysical) {
1820 port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
1823 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1828 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1832 if (output_auto_connect & AutoConnectPhysical) {
1833 port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
1834 } else if (output_auto_connect & AutoConnectMaster) {
1836 port = _master_out->input (x%_master_out->n_inputs())->name();
1840 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1846 vector<string> cports;
1847 uint32_t ni = _control_out->n_inputs();
1849 for (uint32_t n = 0; n < ni; ++n) {
1850 cports.push_back (_control_out->input(n)->name());
1852 bus->set_control_outs (cports);
1859 catch (failed_constructor &err) {
1860 error << _("Session: could not create new audio route.") << endmsg;
1861 return shared_ptr<Route> ((Route*) 0);
1866 Session::add_route (shared_ptr<Route> route)
1869 RCUWriter<RouteList> writer (routes);
1870 shared_ptr<RouteList> r = writer.get_copy ();
1871 r->push_front (route);
1872 resort_routes_using (r);
1875 route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
1876 route->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1877 route->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1878 route->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1880 if (route->master()) {
1881 _master_out = route;
1884 if (route->control()) {
1885 _control_out = route;
1889 save_state (_current_snapshot_name);
1891 RouteAdded (route); /* EMIT SIGNAL */
1895 Session::add_diskstream (Diskstream* dstream)
1897 /* need to do this in case we're rolling at the time, to prevent false underruns */
1898 dstream->do_refill_with_alloc();
1901 Glib::RWLock::WriterLock lm (diskstream_lock);
1902 diskstreams.push_back (dstream);
1905 /* take a reference to the diskstream, preventing it from
1906 ever being deleted until the session itself goes away,
1907 or chooses to remove it for its own purposes.
1911 dstream->set_block_size (current_block_size);
1913 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1914 /* this will connect to future changes, and check the current length */
1915 diskstream_playlist_changed (dstream);
1917 dstream->prepare ();
1920 save_state (_current_snapshot_name);
1922 DiskstreamAdded (dstream); /* EMIT SIGNAL */
1926 Session::remove_route (shared_ptr<Route> route)
1929 RCUWriter<RouteList> writer (routes);
1930 shared_ptr<RouteList> rs = writer.get_copy ();
1933 /* deleting the master out seems like a dumb
1934 idea, but its more of a UI policy issue
1938 if (route == _master_out) {
1939 _master_out = shared_ptr<Route> ((Route*) 0);
1942 if (route == _control_out) {
1943 _control_out = shared_ptr<Route> ((Route*) 0);
1945 /* cancel control outs for all routes */
1947 vector<string> empty;
1949 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1950 (*r)->set_control_outs (empty);
1954 update_route_solo_state ();
1956 /* writer goes out of scope, forces route list update */
1959 // FIXME: audio specific
1961 AudioDiskstream* ds = 0;
1963 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
1964 ds = &at->audio_diskstream();
1970 Glib::RWLock::WriterLock lm (diskstream_lock);
1971 diskstreams.remove (ds);
1977 find_current_end ();
1979 update_latency_compensation (false, false);
1982 /* XXX should we disconnect from the Route's signals ? */
1984 save_state (_current_snapshot_name);
1986 /* all shared ptrs to route should go out of scope here */
1990 Session::route_mute_changed (void* src)
1996 Session::route_solo_changed (void* src, shared_ptr<Route> route)
1998 if (solo_update_disabled) {
2005 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2007 shared_ptr<RouteList> r = routes.reader ();
2009 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2011 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2015 /* don't mess with busses */
2017 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2023 /* don't mess with tracks */
2025 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2030 if ((*i) != route &&
2031 ((*i)->mix_group () == 0 ||
2032 (*i)->mix_group () != route->mix_group () ||
2033 !route->mix_group ()->is_active())) {
2035 if ((*i)->soloed()) {
2037 /* if its already soloed, and solo latching is enabled,
2038 then leave it as it is.
2041 if (_solo_latched) {
2048 solo_update_disabled = true;
2049 (*i)->set_solo (false, src);
2050 solo_update_disabled = false;
2054 bool something_soloed = false;
2055 bool same_thing_soloed = false;
2056 bool signal = false;
2058 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2059 if ((*i)->soloed()) {
2060 something_soloed = true;
2061 if (dynamic_cast<AudioTrack*>((*i).get())) {
2063 same_thing_soloed = true;
2068 same_thing_soloed = true;
2076 if (something_soloed != currently_soloing) {
2078 currently_soloing = something_soloed;
2081 modify_solo_mute (is_track, same_thing_soloed);
2084 SoloActive (currently_soloing);
2091 Session::set_solo_latched (bool yn)
2093 if (yn != _solo_latched) {
2096 ControlChanged (SoloLatch);
2101 Session::update_route_solo_state ()
2104 bool is_track = false;
2105 bool signal = false;
2107 /* caller must hold RouteLock */
2109 /* this is where we actually implement solo by changing
2110 the solo mute setting of each track.
2113 shared_ptr<RouteList> r = routes.reader ();
2115 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2116 if ((*i)->soloed()) {
2118 if (dynamic_cast<AudioTrack*>((*i).get())) {
2125 if (mute != currently_soloing) {
2127 currently_soloing = mute;
2130 if (!is_track && !mute) {
2132 /* nothing is soloed */
2134 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2135 (*i)->set_solo_mute (false);
2145 modify_solo_mute (is_track, mute);
2148 SoloActive (currently_soloing);
2153 Session::modify_solo_mute (bool is_track, bool mute)
2155 shared_ptr<RouteList> r = routes.reader ();
2157 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2161 /* only alter track solo mute */
2163 if (dynamic_cast<AudioTrack*>((*i).get())) {
2164 if ((*i)->soloed()) {
2165 (*i)->set_solo_mute (!mute);
2167 (*i)->set_solo_mute (mute);
2173 /* only alter bus solo mute */
2175 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2177 if ((*i)->soloed()) {
2179 (*i)->set_solo_mute (false);
2183 /* don't mute master or control outs
2184 in response to another bus solo
2187 if ((*i) != _master_out &&
2188 (*i) != _control_out) {
2189 (*i)->set_solo_mute (mute);
2200 Session::catch_up_on_solo ()
2202 /* this is called after set_state() to catch the full solo
2203 state, which can't be correctly determined on a per-route
2204 basis, but needs the global overview that only the session
2207 update_route_solo_state();
2211 Session::route_by_name (string name)
2213 shared_ptr<RouteList> r = routes.reader ();
2215 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2216 if ((*i)->name() == name) {
2221 return shared_ptr<Route> ((Route*) 0);
2225 Session::route_by_id (PBD::ID id)
2227 shared_ptr<RouteList> r = routes.reader ();
2229 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2230 if ((*i)->id() == id) {
2235 return shared_ptr<Route> ((Route*) 0);
2239 Session::route_by_remote_id (uint32_t id)
2241 shared_ptr<RouteList> r = routes.reader ();
2243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2244 if ((*i)->remote_control_id() == id) {
2249 return shared_ptr<Route> ((Route*) 0);
2253 Session::find_current_end ()
2255 if (_state_of_the_state & Loading) {
2259 jack_nframes_t max = get_maximum_extent ();
2261 if (max > end_location->end()) {
2262 end_location->set_end (max);
2264 DurationChanged(); /* EMIT SIGNAL */
2269 Session::get_maximum_extent () const
2271 jack_nframes_t max = 0;
2274 /* Don't take the diskstream lock. Caller must have other ways to
2278 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2279 Playlist* pl = (*i)->playlist();
2280 if ((me = pl->get_maximum_extent()) > max) {
2289 Session::diskstream_by_name (string name)
2291 Glib::RWLock::ReaderLock lm (diskstream_lock);
2293 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2294 if ((*i)->name() == name) {
2303 Session::diskstream_by_id (const PBD::ID& id)
2305 Glib::RWLock::ReaderLock lm (diskstream_lock);
2307 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2308 if ((*i)->id() == id) {
2316 /* AudioRegion management */
2319 Session::new_region_name (string old)
2321 string::size_type last_period;
2323 string::size_type len = old.length() + 64;
2326 if ((last_period = old.find_last_of ('.')) == string::npos) {
2328 /* no period present - add one explicitly */
2331 last_period = old.length() - 1;
2336 number = atoi (old.substr (last_period+1).c_str());
2340 while (number < (UINT_MAX-1)) {
2342 AudioRegionList::const_iterator i;
2347 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2350 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2351 if (i->second->name() == sbuf) {
2356 if (i == audio_regions.end()) {
2361 if (number != (UINT_MAX-1)) {
2365 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2370 Session::region_name (string& result, string base, bool newlevel) const
2377 Glib::Mutex::Lock lm (region_lock);
2379 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2387 /* XXX this is going to be slow. optimize me later */
2392 string::size_type pos;
2394 pos = base.find_last_of ('.');
2396 /* pos may be npos, but then we just use entire base */
2398 subbase = base.substr (0, pos);
2402 bool name_taken = true;
2405 Glib::Mutex::Lock lm (region_lock);
2407 for (int n = 1; n < 5000; ++n) {
2410 snprintf (buf, sizeof (buf), ".%d", n);
2415 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2416 if (i->second->name() == result) {
2429 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2437 Session::add_region (Region* region)
2439 AudioRegion* ar = 0;
2440 AudioRegion* oar = 0;
2444 Glib::Mutex::Lock lm (region_lock);
2446 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2448 AudioRegionList::iterator x;
2450 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2452 oar = dynamic_cast<AudioRegion*> (x->second);
2454 if (ar->region_list_equivalent (*oar)) {
2459 if (x == audio_regions.end()) {
2461 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2463 entry.first = region->id();
2466 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2477 fatal << _("programming error: ")
2478 << X_("unknown region type passed to Session::add_region()")
2485 /* mark dirty because something has changed even if we didn't
2486 add the region to the region list.
2492 region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
2493 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2494 AudioRegionAdded (ar); /* EMIT SIGNAL */
2499 Session::region_changed (Change what_changed, Region* region)
2501 if (what_changed & Region::HiddenChanged) {
2502 /* relay hidden changes */
2503 RegionHiddenChange (region);
2508 Session::region_renamed (Region* region)
2510 add_region (region);
2514 Session::remove_region (Region* region)
2516 AudioRegionList::iterator i;
2517 AudioRegion* ar = 0;
2518 bool removed = false;
2521 Glib::Mutex::Lock lm (region_lock);
2523 if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
2524 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2525 audio_regions.erase (i);
2531 fatal << _("programming error: ")
2532 << X_("unknown region type passed to Session::remove_region()")
2538 /* mark dirty because something has changed even if we didn't
2539 remove the region from the region list.
2545 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2550 Session::find_whole_file_parent (AudioRegion& child)
2552 AudioRegionList::iterator i;
2553 AudioRegion* region;
2554 Glib::Mutex::Lock lm (region_lock);
2556 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2560 if (region->whole_file()) {
2562 if (child.source_equivalent (*region)) {
2572 Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
2574 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2575 (*i)->get_region_list_equivalent_regions (region, result);
2579 Session::destroy_region (Region* region)
2581 AudioRegion* aregion;
2583 if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
2587 if (aregion->playlist()) {
2588 aregion->playlist()->destroy_region (region);
2591 vector<Source*> srcs;
2593 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2594 srcs.push_back (&aregion->source (n));
2597 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2599 if ((*i)->use_cnt() == 0) {
2600 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2602 (afs)->mark_for_remove ();
2612 Session::destroy_regions (list<Region*> regions)
2614 for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
2615 destroy_region (*i);
2621 Session::remove_last_capture ()
2625 Glib::RWLock::ReaderLock lm (diskstream_lock);
2627 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
2628 list<Region*>& l = (*i)->last_capture_regions();
2631 r.insert (r.end(), l.begin(), l.end());
2636 destroy_regions (r);
2641 Session::remove_region_from_region_list (Region& r)
2647 /* Source Management */
2650 Session::add_audio_source (AudioSource* source)
2652 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2655 Glib::Mutex::Lock lm (audio_source_lock);
2656 entry.first = source->id();
2657 entry.second = source;
2658 audio_sources.insert (entry);
2661 source->GoingAway.connect (mem_fun (this, &Session::remove_source));
2664 SourceAdded (source); /* EMIT SIGNAL */
2668 Session::remove_source (Source* source)
2670 AudioSourceList::iterator i;
2673 Glib::Mutex::Lock lm (audio_source_lock);
2675 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2676 audio_sources.erase (i);
2680 if (!_state_of_the_state & InCleanup) {
2682 /* save state so we don't end up with a session file
2683 referring to non-existent sources.
2686 save_state (_current_snapshot_name);
2689 SourceRemoved(source); /* EMIT SIGNAL */
2693 Session::source_by_id (const PBD::ID& id)
2695 Glib::Mutex::Lock lm (audio_source_lock);
2696 AudioSourceList::iterator i;
2699 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2703 /* XXX search MIDI or other searches here */
2709 Session::peak_path_from_audio_path (string audio_path)
2711 /* XXX hardly bombproof! fix me */
2715 res = Glib::path_get_dirname (audio_path);
2716 res = Glib::path_get_dirname (res);
2718 res += peak_dir_name;
2720 res += PBD::basename_nosuffix (audio_path);
2727 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2730 string old_basename = PBD::basename_nosuffix (oldname);
2731 string new_legalized = legalize_for_path (newname);
2733 /* note: we know (or assume) the old path is already valid */
2737 /* destructive file sources have a name of the form:
2739 /path/to/Tnnnn-NAME(%[LR])?.wav
2741 the task here is to replace NAME with the new name.
2744 /* find last slash */
2748 string::size_type slash;
2749 string::size_type dash;
2751 if ((slash = path.find_last_of ('/')) == string::npos) {
2755 dir = path.substr (0, slash+1);
2757 /* '-' is not a legal character for the NAME part of the path */
2759 if ((dash = path.find_last_of ('-')) == string::npos) {
2763 prefix = path.substr (slash+1, dash-(slash+1));
2768 path += new_legalized;
2769 path += ".wav"; /* XXX gag me with a spoon */
2773 /* non-destructive file sources have a name of the form:
2775 /path/to/NAME-nnnnn(%[LR])?.wav
2777 the task here is to replace NAME with the new name.
2782 string::size_type slash;
2783 string::size_type dash;
2784 string::size_type postfix;
2786 /* find last slash */
2788 if ((slash = path.find_last_of ('/')) == string::npos) {
2792 dir = path.substr (0, slash+1);
2794 /* '-' is not a legal character for the NAME part of the path */
2796 if ((dash = path.find_last_of ('-')) == string::npos) {
2800 suffix = path.substr (dash+1);
2802 // Suffix is now everything after the dash. Now we need to eliminate
2803 // the nnnnn part, which is done by either finding a '%' or a '.'
2805 postfix = suffix.find_last_of ("%");
2806 if (postfix == string::npos) {
2807 postfix = suffix.find_last_of ('.');
2810 if (postfix != string::npos) {
2811 suffix = suffix.substr (postfix);
2813 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2817 const uint32_t limit = 10000;
2818 char buf[PATH_MAX+1];
2820 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2822 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2824 if (access (buf, F_OK) != 0) {
2832 error << "FATAL ERROR! Could not find a " << endl;
2841 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2845 char buf[PATH_MAX+1];
2846 const uint32_t limit = 10000;
2850 legalized = legalize_for_path (name);
2852 /* find a "version" of the file name that doesn't exist in
2853 any of the possible directories.
2856 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2858 vector<space_and_path>::iterator i;
2859 uint32_t existing = 0;
2861 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2866 spath += tape_dir_name;
2868 spath += sound_dir_name;
2873 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2874 } else if (nchan == 2) {
2876 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2878 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2880 } else if (nchan < 26) {
2881 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2883 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2891 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2892 } else if (nchan == 2) {
2894 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2896 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2898 } else if (nchan < 26) {
2899 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2901 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2905 if (access (buf, F_OK) == 0) {
2910 if (existing == 0) {
2915 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2916 throw failed_constructor();
2920 /* we now have a unique name for the file, but figure out where to
2927 spath = tape_dir ();
2929 spath = discover_best_sound_dir ();
2932 string::size_type pos = foo.find_last_of ('/');
2934 if (pos == string::npos) {
2937 spath += foo.substr (pos + 1);
2944 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2946 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
2948 /* this might throw failed_constructor(), which is OK */
2951 return new DestructiveFileSource (spath,
2952 Config->get_native_file_data_format(),
2953 Config->get_native_file_header_format(),
2956 return new SndFileSource (spath,
2957 Config->get_native_file_data_format(),
2958 Config->get_native_file_header_format(),
2963 /* Playlist management */
2966 Session::playlist_by_name (string name)
2968 Glib::Mutex::Lock lm (playlist_lock);
2969 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2970 if ((*i)->name() == name) {
2974 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
2975 if ((*i)->name() == name) {
2983 Session::add_playlist (Playlist* playlist)
2985 if (playlist->hidden()) {
2990 Glib::Mutex::Lock lm (playlist_lock);
2991 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
2992 playlists.insert (playlists.begin(), playlist);
2994 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
2995 playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
3001 PlaylistAdded (playlist); /* EMIT SIGNAL */
3005 Session::track_playlist (Playlist* pl, bool inuse)
3007 PlaylistList::iterator x;
3010 Glib::Mutex::Lock lm (playlist_lock);
3013 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3015 unused_playlists.insert (pl);
3017 if ((x = playlists.find (pl)) != playlists.end()) {
3018 playlists.erase (x);
3023 //cerr << "shifting playlist to used: " << pl->name() << endl;
3025 playlists.insert (pl);
3027 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3028 unused_playlists.erase (x);
3035 Session::remove_playlist (Playlist* playlist)
3037 if (_state_of_the_state & Deletion) {
3042 Glib::Mutex::Lock lm (playlist_lock);
3043 // cerr << "removing playlist: " << playlist->name() << endl;
3045 PlaylistList::iterator i;
3047 i = find (playlists.begin(), playlists.end(), playlist);
3049 if (i != playlists.end()) {
3050 playlists.erase (i);
3053 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3054 if (i != unused_playlists.end()) {
3055 unused_playlists.erase (i);
3062 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3066 Session::set_audition (AudioRegion* r)
3068 pending_audition_region = r;
3069 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3070 schedule_butler_transport_work ();
3074 Session::non_realtime_set_audition ()
3076 if (pending_audition_region == (AudioRegion*) 0xfeedface) {
3077 auditioner->audition_current_playlist ();
3078 } else if (pending_audition_region) {
3079 auditioner->audition_region (*pending_audition_region);
3081 pending_audition_region = 0;
3082 AuditionActive (true); /* EMIT SIGNAL */
3086 Session::audition_playlist ()
3088 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3089 ev->set_ptr ((void*) 0xfeedface);
3094 Session::audition_region (Region& r)
3096 AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
3098 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3105 Session::cancel_audition ()
3107 if (auditioner->active()) {
3108 auditioner->cancel_audition ();
3109 AuditionActive (false); /* EMIT SIGNAL */
3114 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3116 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3120 Session::remove_empty_sounds ()
3123 PathScanner scanner;
3128 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3130 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3132 if (AudioFileSource::is_empty (*(*i))) {
3134 unlink ((*i)->c_str());
3136 string peak_path = peak_path_from_audio_path (**i);
3137 unlink (peak_path.c_str());
3143 delete possible_audiofiles;
3147 Session::is_auditioning () const
3149 /* can be called before we have an auditioner object */
3151 return auditioner->active();
3158 Session::set_all_solo (bool yn)
3160 shared_ptr<RouteList> r = routes.reader ();
3162 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3163 if (!(*i)->hidden()) {
3164 (*i)->set_solo (yn, this);
3172 Session::set_all_mute (bool yn)
3174 shared_ptr<RouteList> r = routes.reader ();
3176 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3177 if (!(*i)->hidden()) {
3178 (*i)->set_mute (yn, this);
3186 Session::n_diskstreams () const
3188 Glib::RWLock::ReaderLock lm (diskstream_lock);
3191 for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3192 if (!(*i)->hidden()) {
3200 Session::graph_reordered ()
3202 /* don't do this stuff if we are setting up connections
3203 from a set_state() call.
3206 if (_state_of_the_state & InitialConnecting) {
3210 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3214 /* force all diskstreams to update their capture offset values to
3215 reflect any changes in latencies within the graph.
3218 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3219 (*i)->set_capture_offset ();
3224 Session::record_disenable_all ()
3226 record_enable_change_all (false);
3230 Session::record_enable_all ()
3232 record_enable_change_all (true);
3236 Session::record_enable_change_all (bool yn)
3238 shared_ptr<RouteList> r = routes.reader ();
3240 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3243 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3244 at->set_record_enable (yn, this);
3248 /* since we don't keep rec-enable state, don't mark session dirty */
3252 Session::add_redirect (Redirect* redirect)
3256 PortInsert* port_insert;
3257 PluginInsert* plugin_insert;
3259 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3260 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3261 _port_inserts.insert (_port_inserts.begin(), port_insert);
3262 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3263 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3265 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3268 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3269 _sends.insert (_sends.begin(), send);
3271 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3275 redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
3281 Session::remove_redirect (Redirect* redirect)
3285 PortInsert* port_insert;
3286 PluginInsert* plugin_insert;
3288 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3289 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3290 _port_inserts.remove (port_insert);
3291 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3292 _plugin_inserts.remove (plugin_insert);
3294 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3297 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3298 _sends.remove (send);
3300 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3308 Session::available_capture_duration ()
3310 const double scale = 4096.0 / sizeof (Sample);
3312 if (_total_free_4k_blocks * scale > (double) max_frames) {
3316 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3320 Session::add_connection (ARDOUR::Connection* connection)
3323 Glib::Mutex::Lock guard (connection_lock);
3324 _connections.push_back (connection);
3327 ConnectionAdded (connection); /* EMIT SIGNAL */
3333 Session::remove_connection (ARDOUR::Connection* connection)
3335 bool removed = false;
3338 Glib::Mutex::Lock guard (connection_lock);
3339 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3341 if (i != _connections.end()) {
3342 _connections.erase (i);
3348 ConnectionRemoved (connection); /* EMIT SIGNAL */
3354 ARDOUR::Connection *
3355 Session::connection_by_name (string name) const
3357 Glib::Mutex::Lock lm (connection_lock);
3359 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3360 if ((*i)->name() == name) {
3369 Session::set_edit_mode (EditMode mode)
3374 Glib::Mutex::Lock lm (playlist_lock);
3376 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3377 (*i)->set_edit_mode (mode);
3382 ControlChanged (EditingMode); /* EMIT SIGNAL */
3386 Session::tempo_map_changed (Change ignored)
3393 Session::ensure_passthru_buffers (uint32_t howmany)
3395 while (howmany > _passthru_buffers.size()) {
3397 #ifdef NO_POSIX_MEMALIGN
3398 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3400 posix_memalign((void **)&p,16,current_block_size * 4);
3402 _passthru_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 _silent_buffers.push_back (p);
3416 #ifdef NO_POSIX_MEMALIGN
3417 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3419 posix_memalign((void **)&p,16,current_block_size * 4);
3421 memset (p, 0, sizeof (Sample) * current_block_size);
3422 _send_buffers.push_back (p);
3425 allocate_pan_automation_buffers (current_block_size, howmany, false);
3429 Session::next_send_name ()
3432 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3437 Session::next_insert_name ()
3440 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3444 /* Named Selection management */
3447 Session::named_selection_by_name (string name)
3449 Glib::Mutex::Lock lm (named_selection_lock);
3450 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3451 if ((*i)->name == name) {
3459 Session::add_named_selection (NamedSelection* named_selection)
3462 Glib::Mutex::Lock lm (named_selection_lock);
3463 named_selections.insert (named_selections.begin(), named_selection);
3468 NamedSelectionAdded (); /* EMIT SIGNAL */
3472 Session::remove_named_selection (NamedSelection* named_selection)
3474 bool removed = false;
3477 Glib::Mutex::Lock lm (named_selection_lock);
3479 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3481 if (i != named_selections.end()) {
3483 named_selections.erase (i);
3490 NamedSelectionRemoved (); /* EMIT SIGNAL */
3495 Session::reset_native_file_format ()
3497 // jlc - WHY take routelock?
3498 //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
3499 Glib::RWLock::ReaderLock lm2 (diskstream_lock);
3501 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
3502 (*i)->reset_write_sources (false);
3507 Session::route_name_unique (string n) const
3509 shared_ptr<RouteList> r = routes.reader ();
3511 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3512 if ((*i)->name() == n) {
3521 Session::cleanup_audio_file_source (AudioFileSource& fs)
3523 return fs.move_to_trash (dead_sound_dir_name);
3527 Session::n_playlists () const
3529 Glib::Mutex::Lock lm (playlist_lock);
3530 return playlists.size();
3534 Session::set_solo_model (SoloModel sm)
3536 if (sm != _solo_model) {
3538 ControlChanged (SoloingModel);
3544 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3546 if (!force && howmany <= _npan_buffers) {
3550 if (_pan_automation_buffer) {
3552 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3553 delete [] _pan_automation_buffer[i];
3556 delete [] _pan_automation_buffer;
3559 _pan_automation_buffer = new pan_t*[howmany];
3561 for (uint32_t i = 0; i < howmany; ++i) {
3562 _pan_automation_buffer[i] = new pan_t[nframes];
3565 _npan_buffers = howmany;
3569 Session::freeze (InterThreadInfo& itt)
3571 shared_ptr<RouteList> r = routes.reader ();
3573 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3577 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3578 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3589 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3590 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3594 AudioFileSource* fsource;
3596 char buf[PATH_MAX+1];
3599 jack_nframes_t position;
3600 jack_nframes_t this_chunk;
3601 jack_nframes_t to_do;
3602 vector<Sample*> buffers;
3604 // any bigger than this seems to cause stack overflows in called functions
3605 const jack_nframes_t chunk_size = (128 * 1024)/4;
3607 g_atomic_int_set (&processing_prohibited, 1);
3609 /* call tree *MUST* hold route_lock */
3611 if ((playlist = track.diskstream().playlist()) == 0) {
3615 /* external redirects will be a problem */
3617 if (track.has_external_redirects()) {
3621 nchans = track.audio_diskstream().n_channels();
3623 dir = discover_best_sound_dir ();
3625 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3627 for (x = 0; x < 99999; ++x) {
3628 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3629 if (access (buf, F_OK) != 0) {
3635 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3640 fsource = new SndFileSource (buf,
3641 Config->get_native_file_data_format(),
3642 Config->get_native_file_header_format(),
3647 catch (failed_constructor& err) {
3648 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3652 srcs.push_back(fsource);
3655 /* XXX need to flush all redirects */
3660 /* create a set of reasonably-sized buffers */
3662 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3664 #ifdef NO_POSIX_MEMALIGN
3665 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3667 posix_memalign((void **)&b,16,chunk_size * 4);
3669 buffers.push_back (b);
3672 while (to_do && !itt.cancel) {
3674 this_chunk = min (to_do, chunk_size);
3676 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3681 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3682 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3685 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3691 start += this_chunk;
3692 to_do -= this_chunk;
3694 itt.progress = (float) (1.0 - ((double) to_do / len));
3703 xnow = localtime (&now);
3705 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3706 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3708 afs->update_header (position, *xnow, now);
3712 /* build peakfile for new source */
3714 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3715 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3717 afs->build_peaks ();
3726 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3727 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3729 afs->mark_for_remove ();
3735 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3739 g_atomic_int_set (&processing_prohibited, 0);
3747 Session::get_silent_buffers (uint32_t howmany)
3749 for (uint32_t i = 0; i < howmany; ++i) {
3750 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3752 return _silent_buffers;
3756 Session::ntracks () const
3759 shared_ptr<RouteList> r = routes.reader ();
3761 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3762 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3771 Session::nbusses () const
3774 shared_ptr<RouteList> r = routes.reader ();
3776 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3777 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3786 Session::set_layer_model (LayerModel lm)
3788 if (lm != layer_model) {
3791 ControlChanged (LayeringModel);
3796 Session::set_xfade_model (CrossfadeModel xm)
3798 if (xm != xfade_model) {
3801 ControlChanged (CrossfadingModel);
3806 Session::add_curve(Curve *curve)
3808 curves[curve->id()] = curve;
3812 Session::add_automation_list(AutomationList *al)
3814 automation_lists[al->id()] = al;