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 diskstreams (new DiskstreamList),
260 routes (new RouteList),
261 auditioner ((Auditioner*) 0),
267 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
269 n_physical_outputs = _engine.n_physical_outputs();
270 n_physical_inputs = _engine.n_physical_inputs();
272 first_stage_init (fullpath, snapshot_name);
274 if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
275 throw failed_constructor ();
278 if (second_stage_init (new_session)) {
279 throw failed_constructor ();
282 store_recent_sessions(_name, _path);
284 bool was_dirty = dirty();
286 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
289 DirtyChanged (); /* EMIT SIGNAL */
293 Session::Session (AudioEngine &eng,
295 string snapshot_name,
296 AutoConnectOption input_ac,
297 AutoConnectOption output_ac,
298 uint32_t control_out_channels,
299 uint32_t master_out_channels,
300 uint32_t requested_physical_in,
301 uint32_t requested_physical_out,
302 jack_nframes_t initial_length)
305 _mmc_port (default_mmc_port),
306 _mtc_port (default_mtc_port),
307 _midi_port (default_midi_port),
308 pending_events (2048),
310 diskstreams (new DiskstreamList),
311 routes (new RouteList),
317 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
319 n_physical_outputs = max (requested_physical_out, _engine.n_physical_outputs());
320 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
322 first_stage_init (fullpath, snapshot_name);
324 if (create (new_session, 0, initial_length)) {
325 throw failed_constructor ();
328 if (control_out_channels) {
329 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
336 if (master_out_channels) {
337 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
343 /* prohibit auto-connect to master, because there isn't one */
344 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
347 input_auto_connect = input_ac;
348 output_auto_connect = output_ac;
350 if (second_stage_init (new_session)) {
351 throw failed_constructor ();
354 store_recent_sessions(_name, _path);
356 bool was_dirty = dirty ();
358 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
361 DirtyChanged (); /* EMIT SIGNAL */
367 /* if we got to here, leaving pending capture state around
371 remove_pending_capture_state ();
373 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
374 _engine.remove_session ();
376 GoingAway (); /* EMIT SIGNAL */
382 /* clear history so that no references to objects are held any more */
386 /* clear state tree so that no references to objects are held any more */
392 terminate_butler_thread ();
393 terminate_midi_thread ();
395 if (click_data && click_data != default_click) {
396 delete [] click_data;
399 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
400 delete [] click_emphasis_data;
405 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
409 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
413 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
417 AudioDiskstream::free_working_buffers();
419 #undef TRACK_DESTRUCTION
420 #ifdef TRACK_DESTRUCTION
421 cerr << "delete named selections\n";
422 #endif /* TRACK_DESTRUCTION */
423 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
424 NamedSelectionList::iterator tmp;
433 #ifdef TRACK_DESTRUCTION
434 cerr << "delete playlists\n";
435 #endif /* TRACK_DESTRUCTION */
436 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
437 PlaylistList::iterator tmp;
447 #ifdef TRACK_DESTRUCTION
448 cerr << "delete audio regions\n";
449 #endif /* TRACK_DESTRUCTION */
451 for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
452 i->second->drop_references ();
455 audio_regions.clear ();
457 #ifdef TRACK_DESTRUCTION
458 cerr << "delete routes\n";
459 #endif /* TRACK_DESTRUCTION */
461 RCUWriter<RouteList> writer (routes);
462 boost::shared_ptr<RouteList> r = writer.get_copy ();
463 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
464 (*i)->drop_references ();
467 /* writer goes out of scope and updates master */
472 #ifdef TRACK_DESTRUCTION
473 cerr << "delete diskstreams\n";
474 #endif /* TRACK_DESTRUCTION */
476 RCUWriter<DiskstreamList> dwriter (diskstreams);
477 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
478 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ) {
479 DiskstreamList::iterator tmp;
484 (*i)->drop_references ();
490 diskstreams.flush ();
492 #ifdef TRACK_DESTRUCTION
493 cerr << "delete audio sources\n";
494 #endif /* TRACK_DESTRUCTION */
495 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
496 AudioSourceList::iterator tmp;
506 #ifdef TRACK_DESTRUCTION
507 cerr << "delete mix groups\n";
508 #endif /* TRACK_DESTRUCTION */
509 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
510 list<RouteGroup*>::iterator tmp;
520 #ifdef TRACK_DESTRUCTION
521 cerr << "delete edit groups\n";
522 #endif /* TRACK_DESTRUCTION */
523 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
524 list<RouteGroup*>::iterator tmp;
534 #ifdef TRACK_DESTRUCTION
535 cerr << "delete connections\n";
536 #endif /* TRACK_DESTRUCTION */
537 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
538 ConnectionList::iterator tmp;
548 if (butler_mixdown_buffer) {
549 delete [] butler_mixdown_buffer;
552 if (butler_gain_buffer) {
553 delete [] butler_gain_buffer;
556 Crossfade::set_buffer_size (0);
564 Session::set_worst_io_latencies ()
566 _worst_output_latency = 0;
567 _worst_input_latency = 0;
569 if (!_engine.connected()) {
573 boost::shared_ptr<RouteList> r = routes.reader ();
575 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
576 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
577 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
582 Session::when_engine_running ()
584 string first_physical_output;
586 /* we don't want to run execute this again */
588 first_time_running.disconnect ();
590 set_block_size (_engine.frames_per_cycle());
591 set_frame_rate (_engine.frame_rate());
593 /* every time we reconnect, recompute worst case output latencies */
595 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
597 if (synced_to_jack()) {
598 _engine.transport_stop ();
601 if (Config->get_jack_time_master()) {
602 _engine.transport_locate (_transport_frame);
610 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
612 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
614 /* existing state for Click */
616 if (_click_io->set_state (*child->children().front()) == 0) {
618 _clicking = click_requested;
622 error << _("could not setup Click I/O") << endmsg;
628 /* default state for Click */
630 first_physical_output = _engine.get_nth_physical_output (0);
632 if (first_physical_output.length()) {
633 if (_click_io->add_output_port (first_physical_output, this)) {
634 // relax, even though its an error
636 _clicking = click_requested;
642 catch (failed_constructor& err) {
643 error << _("cannot setup Click I/O") << endmsg;
646 set_worst_io_latencies ();
649 ControlChanged (Clicking); /* EMIT SIGNAL */
652 if (auditioner == 0) {
654 /* we delay creating the auditioner till now because
655 it makes its own connections to ports named
656 in the ARDOUR_RC config file. the engine has
657 to be running for this to work.
661 auditioner.reset (new Auditioner (*this));
664 catch (failed_constructor& err) {
665 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
669 /* Create a set of Connection objects that map
670 to the physical outputs currently available
675 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
677 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
679 Connection* c = new OutputConnection (buf, true);
682 c->add_connection (0, _engine.get_nth_physical_output (np));
687 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
689 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
691 Connection* c = new InputConnection (buf, true);
694 c->add_connection (0, _engine.get_nth_physical_input (np));
701 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
703 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
705 Connection* c = new OutputConnection (buf, true);
709 c->add_connection (0, _engine.get_nth_physical_output (np));
710 c->add_connection (1, _engine.get_nth_physical_output (np+1));
715 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
717 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
719 Connection* c = new InputConnection (buf, true);
723 c->add_connection (0, _engine.get_nth_physical_input (np));
724 c->add_connection (1, _engine.get_nth_physical_input (np+1));
733 /* create master/control ports */
738 /* force the master to ignore any later call to this */
740 if (_master_out->pending_state_node) {
741 _master_out->ports_became_legal();
744 /* no panner resets till we are through */
746 _master_out->defer_pan_reset ();
748 while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
749 if (_master_out->add_input_port ("", this)) {
750 error << _("cannot setup master inputs")
756 while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
757 if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
758 error << _("cannot setup master outputs")
765 _master_out->allow_pan_reset ();
769 Connection* c = new OutputConnection (_("Master Out"), true);
771 for (uint32_t n = 0; n < _master_out->n_inputs (); ++n) {
773 c->add_connection ((int) n, _master_out->input(n)->name());
780 /* catch up on send+insert cnts */
784 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
787 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
788 if (id > insert_cnt) {
796 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
799 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
806 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
808 /* hook us up to the engine */
810 _engine.set_session (this);
815 osc->set_session (*this);
818 _state_of_the_state = Clean;
820 DirtyChanged (); /* EMIT SIGNAL */
824 Session::hookup_io ()
826 /* stop graph reordering notifications from
827 causing resorts, etc.
830 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
832 /* Tell all IO objects to create their ports */
839 while ((int) _control_out->n_inputs() < _control_out->input_maximum()) {
840 if (_control_out->add_input_port ("", this)) {
841 error << _("cannot setup control inputs")
847 while ((int) _control_out->n_outputs() < _control_out->output_maximum()) {
848 if (_control_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
849 error << _("cannot set up master outputs")
857 /* Tell all IO objects to connect themselves together */
859 IO::enable_connecting ();
861 /* Now reset all panners */
863 IO::reset_panners ();
865 /* Anyone who cares about input state, wake up and do something */
867 IOConnectionsComplete (); /* EMIT SIGNAL */
869 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
871 /* now handle the whole enchilada as if it was one
877 /* update mixer solo state */
883 Session::playlist_length_changed (Playlist* pl)
885 /* we can't just increase end_location->end() if pl->get_maximum_extent()
886 if larger. if the playlist used to be the longest playlist,
887 and its now shorter, we have to decrease end_location->end(). hence,
888 we have to iterate over all diskstreams and check the
889 playlists currently in use.
895 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
899 if ((playlist = dstream->playlist()) != 0) {
900 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
903 /* see comment in playlist_length_changed () */
908 Session::record_enabling_legal () const
910 /* this used to be in here, but survey says.... we don't need to restrict it */
911 // if (record_status() == Recording) {
922 Session::set_auto_play (bool yn)
924 if (auto_play != yn) {
927 ControlChanged (AutoPlay);
932 Session::set_auto_return (bool yn)
934 if (auto_return != yn) {
937 ControlChanged (AutoReturn);
942 Session::set_crossfades_active (bool yn)
944 if (crossfades_active != yn) {
945 crossfades_active = yn;
947 ControlChanged (CrossFadesActive);
952 Session::set_do_not_record_plugins (bool yn)
954 if (do_not_record_plugins != yn) {
955 do_not_record_plugins = yn;
957 ControlChanged (RecordingPlugins);
962 Session::set_auto_input (bool yn)
964 if (auto_input != yn) {
967 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
968 /* auto-input only makes a difference if we're rolling */
970 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
972 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
973 if ((*i)->record_enabled ()) {
974 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
975 (*i)->monitor_input (!auto_input);
981 ControlChanged (AutoInput);
986 Session::reset_input_monitor_state ()
988 if (transport_rolling()) {
990 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
992 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
993 if ((*i)->record_enabled ()) {
994 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
995 (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
999 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1001 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1002 if ((*i)->record_enabled ()) {
1003 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1004 (*i)->monitor_input (Config->get_use_hardware_monitoring());
1012 Session::set_input_auto_connect (bool yn)
1015 input_auto_connect = AutoConnectOption (input_auto_connect|AutoConnectPhysical);
1017 input_auto_connect = AutoConnectOption (input_auto_connect|~AutoConnectPhysical);
1023 Session::get_input_auto_connect () const
1025 return (input_auto_connect & AutoConnectPhysical);
1029 Session::set_output_auto_connect (AutoConnectOption aco)
1031 output_auto_connect = aco;
1036 Session::auto_punch_start_changed (Location* location)
1038 replace_event (Event::PunchIn, location->start());
1040 if (get_record_enabled() && get_punch_in()) {
1041 /* capture start has been changed, so save new pending state */
1042 save_state ("", true);
1047 Session::auto_punch_end_changed (Location* location)
1049 jack_nframes_t when_to_stop = location->end();
1050 // when_to_stop += _worst_output_latency + _worst_input_latency;
1051 replace_event (Event::PunchOut, when_to_stop);
1055 Session::auto_punch_changed (Location* location)
1057 jack_nframes_t when_to_stop = location->end();
1059 replace_event (Event::PunchIn, location->start());
1060 //when_to_stop += _worst_output_latency + _worst_input_latency;
1061 replace_event (Event::PunchOut, when_to_stop);
1065 Session::auto_loop_changed (Location* location)
1067 replace_event (Event::AutoLoop, location->end(), location->start());
1069 if (transport_rolling() && get_auto_loop()) {
1071 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1073 if (_transport_frame > location->end()) {
1074 // relocate to beginning of loop
1075 clear_events (Event::LocateRoll);
1077 request_locate (location->start(), true);
1080 else if (seamless_loop && !loop_changing) {
1082 // schedule a locate-roll to refill the diskstreams at the
1083 // previous loop end
1084 loop_changing = true;
1086 if (location->end() > last_loopend) {
1087 clear_events (Event::LocateRoll);
1088 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1095 last_loopend = location->end();
1100 Session::set_auto_punch_location (Location* location)
1104 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1105 auto_punch_start_changed_connection.disconnect();
1106 auto_punch_end_changed_connection.disconnect();
1107 auto_punch_changed_connection.disconnect();
1108 existing->set_auto_punch (false, this);
1109 remove_event (existing->start(), Event::PunchIn);
1110 clear_events (Event::PunchOut);
1111 auto_punch_location_changed (0);
1116 if (location == 0) {
1120 if (location->end() <= location->start()) {
1121 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1125 auto_punch_start_changed_connection.disconnect();
1126 auto_punch_end_changed_connection.disconnect();
1127 auto_punch_changed_connection.disconnect();
1129 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1130 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1131 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1133 location->set_auto_punch (true, this);
1134 auto_punch_location_changed (location);
1138 Session::set_punch_in (bool yn)
1140 if (punch_in == yn) {
1146 if ((location = _locations.auto_punch_location()) != 0) {
1147 if ((punch_in = yn) == true) {
1148 replace_event (Event::PunchIn, location->start());
1150 remove_event (location->start(), Event::PunchIn);
1155 ControlChanged (PunchIn); /* EMIT SIGNAL */
1159 Session::set_punch_out (bool yn)
1161 if (punch_out == yn) {
1167 if ((location = _locations.auto_punch_location()) != 0) {
1168 if ((punch_out = yn) == true) {
1169 replace_event (Event::PunchOut, location->end());
1171 clear_events (Event::PunchOut);
1176 ControlChanged (PunchOut); /* EMIT SIGNAL */
1180 Session::set_auto_loop_location (Location* location)
1184 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1185 auto_loop_start_changed_connection.disconnect();
1186 auto_loop_end_changed_connection.disconnect();
1187 auto_loop_changed_connection.disconnect();
1188 existing->set_auto_loop (false, this);
1189 remove_event (existing->end(), Event::AutoLoop);
1190 auto_loop_location_changed (0);
1195 if (location == 0) {
1199 if (location->end() <= location->start()) {
1200 error << _("Session: you can't use a mark for auto loop") << endmsg;
1204 last_loopend = location->end();
1206 auto_loop_start_changed_connection.disconnect();
1207 auto_loop_end_changed_connection.disconnect();
1208 auto_loop_changed_connection.disconnect();
1210 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1211 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1212 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1214 location->set_auto_loop (true, this);
1215 auto_loop_location_changed (location);
1219 Session::locations_added (Location* ignored)
1225 Session::locations_changed ()
1227 _locations.apply (*this, &Session::handle_locations_changed);
1231 Session::handle_locations_changed (Locations::LocationList& locations)
1233 Locations::LocationList::iterator i;
1235 bool set_loop = false;
1236 bool set_punch = false;
1238 for (i = locations.begin(); i != locations.end(); ++i) {
1242 if (location->is_auto_punch()) {
1243 set_auto_punch_location (location);
1246 if (location->is_auto_loop()) {
1247 set_auto_loop_location (location);
1254 set_auto_loop_location (0);
1257 set_auto_punch_location (0);
1264 Session::enable_record ()
1266 /* XXX really atomic compare+swap here */
1267 if (g_atomic_int_get (&_record_status) != Recording) {
1268 g_atomic_int_set (&_record_status, Recording);
1269 _last_record_location = _transport_frame;
1270 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
1272 if (Config->get_use_hardware_monitoring() && auto_input) {
1273 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1274 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1275 if ((*i)->record_enabled ()) {
1276 (*i)->monitor_input (true);
1281 RecordStateChanged ();
1286 Session::disable_record (bool rt_context, bool force)
1290 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1292 if (!Config->get_latched_record_enable () || force) {
1293 g_atomic_int_set (&_record_status, Disabled);
1295 if (rs == Recording) {
1296 g_atomic_int_set (&_record_status, Enabled);
1300 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
1302 if (Config->get_use_hardware_monitoring() && auto_input) {
1303 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1305 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1306 if ((*i)->record_enabled ()) {
1307 (*i)->monitor_input (false);
1312 RecordStateChanged (); /* emit signal */
1315 remove_pending_capture_state ();
1321 Session::step_back_from_record ()
1323 g_atomic_int_set (&_record_status, Enabled);
1325 if (Config->get_use_hardware_monitoring()) {
1326 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1328 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1329 if (auto_input && (*i)->record_enabled ()) {
1330 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1331 (*i)->monitor_input (false);
1338 Session::maybe_enable_record ()
1340 g_atomic_int_set (&_record_status, Enabled);
1342 /* XXX this save should really happen in another thread. its needed so that
1343 pending capture state can be recovered if we crash.
1346 save_state ("", true);
1348 if (_transport_speed) {
1353 send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
1354 RecordStateChanged (); /* EMIT SIGNAL */
1361 Session::audible_frame () const
1364 jack_nframes_t offset;
1367 /* the first of these two possible settings for "offset"
1368 mean that the audible frame is stationary until
1369 audio emerges from the latency compensation
1372 the second means that the audible frame is stationary
1373 until audio would emerge from a physical port
1374 in the absence of any plugin latency compensation
1377 offset = _worst_output_latency;
1379 if (offset > current_block_size) {
1380 offset -= current_block_size;
1382 /* XXX is this correct? if we have no external
1383 physical connections and everything is internal
1384 then surely this is zero? still, how
1385 likely is that anyway?
1387 offset = current_block_size;
1390 if (synced_to_jack()) {
1391 tf = _engine.transport_frame();
1393 tf = _transport_frame;
1396 if (_transport_speed == 0) {
1406 if (!non_realtime_work_pending()) {
1410 /* take latency into account */
1419 Session::set_frame_rate (jack_nframes_t frames_per_second)
1421 /** \fn void Session::set_frame_size(jack_nframes_t)
1422 the AudioEngine object that calls this guarantees
1423 that it will not be called while we are also in
1424 ::process(). Its fine to do things that block
1428 _current_frame_rate = frames_per_second;
1429 _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second;
1431 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1433 // XXX we need some equivalent to this, somehow
1434 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1438 /* XXX need to reset/reinstantiate all LADSPA plugins */
1442 Session::set_block_size (jack_nframes_t nframes)
1444 /* the AudioEngine guarantees
1445 that it will not be called while we are also in
1446 ::process(). It is therefore fine to do things that block
1451 vector<Sample*>::iterator i;
1454 current_block_size = nframes;
1456 for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) {
1460 for (vector<Sample*>::iterator i = _silent_buffers.begin(); i != _silent_buffers.end(); ++i) {
1464 _passthru_buffers.clear ();
1465 _silent_buffers.clear ();
1467 ensure_passthru_buffers (np);
1469 for (vector<Sample*>::iterator i = _send_buffers.begin(); i != _send_buffers.end(); ++i) {
1473 #ifdef NO_POSIX_MEMALIGN
1474 buf = (Sample *) malloc(current_block_size * sizeof(Sample));
1476 posix_memalign((void **)&buf,16,current_block_size * 4);
1480 memset (*i, 0, sizeof (Sample) * current_block_size);
1484 if (_gain_automation_buffer) {
1485 delete [] _gain_automation_buffer;
1487 _gain_automation_buffer = new gain_t[nframes];
1489 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1491 boost::shared_ptr<RouteList> r = routes.reader ();
1493 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1494 (*i)->set_block_size (nframes);
1497 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1498 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1499 (*i)->set_block_size (nframes);
1502 set_worst_io_latencies ();
1507 Session::set_default_fade (float steepness, float fade_msecs)
1510 jack_nframes_t fade_frames;
1512 /* Don't allow fade of less 1 frame */
1514 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1521 fade_frames = (jack_nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1525 default_fade_msecs = fade_msecs;
1526 default_fade_steepness = steepness;
1529 // jlc, WTF is this!
1530 Glib::RWLock::ReaderLock lm (route_lock);
1531 AudioRegion::set_default_fade (steepness, fade_frames);
1536 /* XXX have to do this at some point */
1537 /* foreach region using default fade, reset, then
1538 refill_all_diskstream_buffers ();
1543 struct RouteSorter {
1544 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1545 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1547 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1550 if (r1->fed_by.empty()) {
1551 if (r2->fed_by.empty()) {
1552 /* no ardour-based connections inbound to either route. just use signal order */
1553 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1555 /* r2 has connections, r1 does not; run r1 early */
1559 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1566 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1568 shared_ptr<Route> r2;
1570 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1571 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1575 /* make a copy of the existing list of routes that feed r1 */
1577 set<shared_ptr<Route> > existing = r1->fed_by;
1579 /* for each route that feeds r1, recurse, marking it as feeding
1583 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1586 /* r2 is a route that feeds r1 which somehow feeds base. mark
1587 base as being fed by r2
1590 rbase->fed_by.insert (r2);
1594 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1598 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1602 /* now recurse, so that we can mark base as being fed by
1603 all routes that feed r2
1606 trace_terminal (r2, rbase);
1613 Session::resort_routes ()
1615 /* don't do anything here with signals emitted
1616 by Routes while we are being destroyed.
1619 if (_state_of_the_state & Deletion) {
1626 RCUWriter<RouteList> writer (routes);
1627 shared_ptr<RouteList> r = writer.get_copy ();
1628 resort_routes_using (r);
1629 /* writer goes out of scope and forces update */
1634 Session::resort_routes_using (shared_ptr<RouteList> r)
1636 RouteList::iterator i, j;
1638 for (i = r->begin(); i != r->end(); ++i) {
1640 (*i)->fed_by.clear ();
1642 for (j = r->begin(); j != r->end(); ++j) {
1644 /* although routes can feed themselves, it will
1645 cause an endless recursive descent if we
1646 detect it. so don't bother checking for
1654 if ((*j)->feeds (*i)) {
1655 (*i)->fed_by.insert (*j);
1660 for (i = r->begin(); i != r->end(); ++i) {
1661 trace_terminal (*i, *i);
1668 cerr << "finished route resort\n";
1670 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1671 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1678 list<boost::shared_ptr<AudioTrack> >
1679 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1681 char track_name[32];
1682 uint32_t track_id = 0;
1684 uint32_t channels_used = 0;
1686 RouteList new_routes;
1687 list<boost::shared_ptr<AudioTrack> > ret;
1689 /* count existing audio tracks */
1692 shared_ptr<RouteList> r = routes.reader ();
1694 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1695 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1696 if (!(*i)->hidden()) {
1698 channels_used += (*i)->n_inputs();
1704 vector<string> physinputs;
1705 vector<string> physoutputs;
1706 uint32_t nphysical_in;
1707 uint32_t nphysical_out;
1709 _engine.get_physical_outputs (physoutputs);
1710 _engine.get_physical_inputs (physinputs);
1714 /* check for duplicate route names, since we might have pre-existing
1715 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1716 save, close,restart,add new route - first named route is now
1724 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1726 if (route_by_name (track_name) == 0) {
1730 } while (track_id < (UINT_MAX-1));
1732 if (input_auto_connect & AutoConnectPhysical) {
1733 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1738 if (output_auto_connect & AutoConnectPhysical) {
1739 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1745 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1747 if (track->ensure_io (input_channels, output_channels, false, this)) {
1748 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1749 input_channels, output_channels)
1754 for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
1758 if (input_auto_connect & AutoConnectPhysical) {
1759 port = physinputs[(channels_used+x)%nphysical_in];
1762 if (port.length() && track->connect_input (track->input (x), port, this)) {
1768 for (uint32_t x = 0; x < track->n_outputs(); ++x) {
1772 if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
1773 port = physoutputs[(channels_used+x)%nphysical_out];
1774 } else if (output_auto_connect & AutoConnectMaster) {
1776 port = _master_out->input (x%_master_out->n_inputs())->name();
1780 if (port.length() && track->connect_output (track->output (x), port, this)) {
1785 channels_used += track->n_inputs ();
1788 vector<string> cports;
1789 uint32_t ni = _control_out->n_inputs();
1791 for (n = 0; n < ni; ++n) {
1792 cports.push_back (_control_out->input(n)->name());
1795 track->set_control_outs (cports);
1798 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1799 track->set_remote_control_id (ntracks());
1801 new_routes.push_back (track);
1802 ret.push_back (track);
1805 catch (failed_constructor &err) {
1806 error << _("Session: could not create new audio track.") << endmsg;
1807 // XXX should we delete the tracks already created?
1815 if (!new_routes.empty()) {
1816 add_routes (new_routes, false);
1817 save_state (_current_snapshot_name);
1824 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1827 uint32_t bus_id = 1;
1832 /* count existing audio busses */
1835 shared_ptr<RouteList> r = routes.reader ();
1837 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1838 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1839 if (!(*i)->hidden()) {
1846 vector<string> physinputs;
1847 vector<string> physoutputs;
1849 _engine.get_physical_outputs (physoutputs);
1850 _engine.get_physical_inputs (physinputs);
1857 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1859 if (route_by_name (bus_name) == 0) {
1863 } while (bus_id < (UINT_MAX-1));
1866 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1868 if (bus->ensure_io (input_channels, output_channels, false, this)) {
1869 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1870 input_channels, output_channels)
1874 for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
1878 if (input_auto_connect & AutoConnectPhysical) {
1879 port = physinputs[((n+x)%n_physical_inputs)];
1882 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1887 for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
1891 if (output_auto_connect & AutoConnectPhysical) {
1892 port = physoutputs[((n+x)%n_physical_outputs)];
1893 } else if (output_auto_connect & AutoConnectMaster) {
1895 port = _master_out->input (x%_master_out->n_inputs())->name();
1899 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1905 vector<string> cports;
1906 uint32_t ni = _control_out->n_inputs();
1908 for (uint32_t n = 0; n < ni; ++n) {
1909 cports.push_back (_control_out->input(n)->name());
1911 bus->set_control_outs (cports);
1914 ret.push_back (bus);
1918 catch (failed_constructor &err) {
1919 error << _("Session: could not create new audio route.") << endmsg;
1928 add_routes (ret, false);
1929 save_state (_current_snapshot_name);
1937 Session::add_routes (RouteList& new_routes, bool save)
1940 RCUWriter<RouteList> writer (routes);
1941 shared_ptr<RouteList> r = writer.get_copy ();
1942 r->insert (r->end(), new_routes.begin(), new_routes.end());
1943 resort_routes_using (r);
1946 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1947 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), (*x)));
1948 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1949 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1950 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1952 if ((*x)->master()) {
1956 if ((*x)->control()) {
1957 _control_out = (*x);
1964 save_state (_current_snapshot_name);
1967 RouteAdded (new_routes); /* EMIT SIGNAL */
1971 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1973 /* need to do this in case we're rolling at the time, to prevent false underruns */
1974 dstream->do_refill_with_alloc();
1977 RCUWriter<DiskstreamList> writer (diskstreams);
1978 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1979 ds->push_back (dstream);
1982 dstream->set_block_size (current_block_size);
1984 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1985 /* this will connect to future changes, and check the current length */
1986 diskstream_playlist_changed (dstream);
1988 dstream->prepare ();
1992 Session::remove_route (shared_ptr<Route> route)
1995 RCUWriter<RouteList> writer (routes);
1996 shared_ptr<RouteList> rs = writer.get_copy ();
1999 /* deleting the master out seems like a dumb
2000 idea, but its more of a UI policy issue
2004 if (route == _master_out) {
2005 _master_out = shared_ptr<Route> ((Route*) 0);
2008 if (route == _control_out) {
2009 _control_out = shared_ptr<Route> ((Route*) 0);
2011 /* cancel control outs for all routes */
2013 vector<string> empty;
2015 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2016 (*r)->set_control_outs (empty);
2020 update_route_solo_state ();
2022 /* writer goes out of scope, forces route list update */
2025 // FIXME: audio specific
2027 boost::shared_ptr<AudioDiskstream> ds;
2029 if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
2030 ds = at->audio_diskstream();
2036 RCUWriter<DiskstreamList> dsl (diskstreams);
2037 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2042 find_current_end ();
2044 update_latency_compensation (false, false);
2047 /* XXX should we disconnect from the Route's signals ? */
2049 save_state (_current_snapshot_name);
2051 /* try to cause everyone to drop their references */
2053 route->drop_references ();
2057 Session::route_mute_changed (void* src)
2063 Session::route_solo_changed (void* src, shared_ptr<Route> route)
2065 if (solo_update_disabled) {
2072 is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
2074 shared_ptr<RouteList> r = routes.reader ();
2076 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2078 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2082 /* don't mess with busses */
2084 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
2090 /* don't mess with tracks */
2092 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
2097 if ((*i) != route &&
2098 ((*i)->mix_group () == 0 ||
2099 (*i)->mix_group () != route->mix_group () ||
2100 !route->mix_group ()->is_active())) {
2102 if ((*i)->soloed()) {
2104 /* if its already soloed, and solo latching is enabled,
2105 then leave it as it is.
2108 if (_solo_latched) {
2115 solo_update_disabled = true;
2116 (*i)->set_solo (false, src);
2117 solo_update_disabled = false;
2121 bool something_soloed = false;
2122 bool same_thing_soloed = false;
2123 bool signal = false;
2125 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2126 if ((*i)->soloed()) {
2127 something_soloed = true;
2128 if (dynamic_cast<AudioTrack*>((*i).get())) {
2130 same_thing_soloed = true;
2135 same_thing_soloed = true;
2143 if (something_soloed != currently_soloing) {
2145 currently_soloing = something_soloed;
2148 modify_solo_mute (is_track, same_thing_soloed);
2151 SoloActive (currently_soloing);
2158 Session::set_solo_latched (bool yn)
2160 if (yn != _solo_latched) {
2163 ControlChanged (SoloLatch);
2168 Session::update_route_solo_state ()
2171 bool is_track = false;
2172 bool signal = false;
2174 /* caller must hold RouteLock */
2176 /* this is where we actually implement solo by changing
2177 the solo mute setting of each track.
2180 shared_ptr<RouteList> r = routes.reader ();
2182 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2183 if ((*i)->soloed()) {
2185 if (dynamic_cast<AudioTrack*>((*i).get())) {
2192 if (mute != currently_soloing) {
2194 currently_soloing = mute;
2197 if (!is_track && !mute) {
2199 /* nothing is soloed */
2201 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2202 (*i)->set_solo_mute (false);
2212 modify_solo_mute (is_track, mute);
2215 SoloActive (currently_soloing);
2220 Session::modify_solo_mute (bool is_track, bool mute)
2222 shared_ptr<RouteList> r = routes.reader ();
2224 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2228 /* only alter track solo mute */
2230 if (dynamic_cast<AudioTrack*>((*i).get())) {
2231 if ((*i)->soloed()) {
2232 (*i)->set_solo_mute (!mute);
2234 (*i)->set_solo_mute (mute);
2240 /* only alter bus solo mute */
2242 if (!dynamic_cast<AudioTrack*>((*i).get())) {
2244 if ((*i)->soloed()) {
2246 (*i)->set_solo_mute (false);
2250 /* don't mute master or control outs
2251 in response to another bus solo
2254 if ((*i) != _master_out &&
2255 (*i) != _control_out) {
2256 (*i)->set_solo_mute (mute);
2267 Session::catch_up_on_solo ()
2269 /* this is called after set_state() to catch the full solo
2270 state, which can't be correctly determined on a per-route
2271 basis, but needs the global overview that only the session
2274 update_route_solo_state();
2278 Session::route_by_name (string name)
2280 shared_ptr<RouteList> r = routes.reader ();
2282 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2283 if ((*i)->name() == name) {
2288 return shared_ptr<Route> ((Route*) 0);
2292 Session::route_by_id (PBD::ID id)
2294 shared_ptr<RouteList> r = routes.reader ();
2296 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2297 if ((*i)->id() == id) {
2302 return shared_ptr<Route> ((Route*) 0);
2306 Session::route_by_remote_id (uint32_t id)
2308 shared_ptr<RouteList> r = routes.reader ();
2310 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2311 if ((*i)->remote_control_id() == id) {
2316 return shared_ptr<Route> ((Route*) 0);
2320 Session::find_current_end ()
2322 if (_state_of_the_state & Loading) {
2326 jack_nframes_t max = get_maximum_extent ();
2328 if (max > end_location->end()) {
2329 end_location->set_end (max);
2331 DurationChanged(); /* EMIT SIGNAL */
2336 Session::get_maximum_extent () const
2338 jack_nframes_t max = 0;
2341 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2343 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2344 Playlist* pl = (*i)->playlist();
2345 if ((me = pl->get_maximum_extent()) > max) {
2353 boost::shared_ptr<Diskstream>
2354 Session::diskstream_by_name (string name)
2356 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2358 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2359 if ((*i)->name() == name) {
2364 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2367 boost::shared_ptr<Diskstream>
2368 Session::diskstream_by_id (const PBD::ID& id)
2370 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2372 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2373 if ((*i)->id() == id) {
2378 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2381 /* AudioRegion management */
2384 Session::new_region_name (string old)
2386 string::size_type last_period;
2388 string::size_type len = old.length() + 64;
2391 if ((last_period = old.find_last_of ('.')) == string::npos) {
2393 /* no period present - add one explicitly */
2396 last_period = old.length() - 1;
2401 number = atoi (old.substr (last_period+1).c_str());
2405 while (number < (UINT_MAX-1)) {
2407 AudioRegionList::const_iterator i;
2412 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2415 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2416 if (i->second->name() == sbuf) {
2421 if (i == audio_regions.end()) {
2426 if (number != (UINT_MAX-1)) {
2430 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2435 Session::region_name (string& result, string base, bool newlevel) const
2442 Glib::Mutex::Lock lm (region_lock);
2444 snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
2452 /* XXX this is going to be slow. optimize me later */
2457 string::size_type pos;
2459 pos = base.find_last_of ('.');
2461 /* pos may be npos, but then we just use entire base */
2463 subbase = base.substr (0, pos);
2467 bool name_taken = true;
2470 Glib::Mutex::Lock lm (region_lock);
2472 for (int n = 1; n < 5000; ++n) {
2475 snprintf (buf, sizeof (buf), ".%d", n);
2480 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2481 if (i->second->name() == result) {
2494 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2502 Session::add_region (boost::shared_ptr<Region> region)
2504 boost::shared_ptr<AudioRegion> ar;
2505 boost::shared_ptr<AudioRegion> oar;
2509 Glib::Mutex::Lock lm (region_lock);
2511 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2513 AudioRegionList::iterator x;
2515 for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
2517 oar = boost::dynamic_pointer_cast<AudioRegion> (x->second);
2519 if (ar->region_list_equivalent (oar)) {
2524 if (x == audio_regions.end()) {
2526 pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
2528 entry.first = region->id();
2531 pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
2543 fatal << _("programming error: ")
2544 << X_("unknown region type passed to Session::add_region()")
2551 /* mark dirty because something has changed even if we didn't
2552 add the region to the region list.
2558 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
2559 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
2560 AudioRegionAdded (ar); /* EMIT SIGNAL */
2565 Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
2567 if (what_changed & Region::HiddenChanged) {
2568 /* relay hidden changes */
2569 RegionHiddenChange (region);
2574 Session::region_renamed (boost::shared_ptr<Region> region)
2576 add_region (region);
2580 Session::remove_region (boost::shared_ptr<Region> region)
2582 AudioRegionList::iterator i;
2583 boost::shared_ptr<AudioRegion> ar;
2584 bool removed = false;
2587 Glib::Mutex::Lock lm (region_lock);
2589 if ((ar = boost::dynamic_pointer_cast<AudioRegion> (region)) != 0) {
2590 if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
2591 audio_regions.erase (i);
2597 fatal << _("programming error: ")
2598 << X_("unknown region type passed to Session::remove_region()")
2604 /* mark dirty because something has changed even if we didn't
2605 remove the region from the region list.
2611 AudioRegionRemoved(ar); /* EMIT SIGNAL */
2615 boost::shared_ptr<AudioRegion>
2616 Session::find_whole_file_parent (boost::shared_ptr<AudioRegion> child)
2618 AudioRegionList::iterator i;
2619 boost::shared_ptr<AudioRegion> region;
2620 Glib::Mutex::Lock lm (region_lock);
2622 for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
2626 if (region->whole_file()) {
2628 if (child->source_equivalent (region)) {
2634 return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
2638 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2640 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2641 (*i)->get_region_list_equivalent_regions (region, result);
2645 Session::destroy_region (boost::shared_ptr<Region> region)
2647 boost::shared_ptr<AudioRegion> aregion;
2649 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2653 if (aregion->playlist()) {
2654 aregion->playlist()->destroy_region (region);
2657 vector<Source*> srcs;
2659 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2660 srcs.push_back (&aregion->source (n));
2663 for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2665 if ((*i)->use_cnt() == 0) {
2666 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
2668 (afs)->mark_for_remove ();
2678 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2680 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2681 destroy_region (*i);
2687 Session::remove_last_capture ()
2689 list<boost::shared_ptr<Region> > r;
2691 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2693 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2694 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2697 r.insert (r.end(), l.begin(), l.end());
2702 destroy_regions (r);
2707 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2713 /* Source Management */
2716 Session::add_audio_source (AudioSource* source)
2718 pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
2721 Glib::Mutex::Lock lm (audio_source_lock);
2722 entry.first = source->id();
2723 entry.second = source;
2724 audio_sources.insert (entry);
2727 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), source));
2730 SourceAdded (source); /* EMIT SIGNAL */
2734 Session::remove_source (Source* source)
2736 AudioSourceList::iterator i;
2739 Glib::Mutex::Lock lm (audio_source_lock);
2741 if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
2742 audio_sources.erase (i);
2746 if (!_state_of_the_state & InCleanup) {
2748 /* save state so we don't end up with a session file
2749 referring to non-existent sources.
2752 save_state (_current_snapshot_name);
2755 SourceRemoved(source); /* EMIT SIGNAL */
2759 Session::source_by_id (const PBD::ID& id)
2761 Glib::Mutex::Lock lm (audio_source_lock);
2762 AudioSourceList::iterator i;
2765 if ((i = audio_sources.find (id)) != audio_sources.end()) {
2769 /* XXX search MIDI or other searches here */
2775 Session::peak_path_from_audio_path (string audio_path)
2777 /* XXX hardly bombproof! fix me */
2781 res = Glib::path_get_dirname (audio_path);
2782 res = Glib::path_get_dirname (res);
2784 res += peak_dir_name;
2786 res += PBD::basename_nosuffix (audio_path);
2793 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2796 string old_basename = PBD::basename_nosuffix (oldname);
2797 string new_legalized = legalize_for_path (newname);
2799 /* note: we know (or assume) the old path is already valid */
2803 /* destructive file sources have a name of the form:
2805 /path/to/Tnnnn-NAME(%[LR])?.wav
2807 the task here is to replace NAME with the new name.
2810 /* find last slash */
2814 string::size_type slash;
2815 string::size_type dash;
2817 if ((slash = path.find_last_of ('/')) == string::npos) {
2821 dir = path.substr (0, slash+1);
2823 /* '-' is not a legal character for the NAME part of the path */
2825 if ((dash = path.find_last_of ('-')) == string::npos) {
2829 prefix = path.substr (slash+1, dash-(slash+1));
2834 path += new_legalized;
2835 path += ".wav"; /* XXX gag me with a spoon */
2839 /* non-destructive file sources have a name of the form:
2841 /path/to/NAME-nnnnn(%[LR])?.wav
2843 the task here is to replace NAME with the new name.
2848 string::size_type slash;
2849 string::size_type dash;
2850 string::size_type postfix;
2852 /* find last slash */
2854 if ((slash = path.find_last_of ('/')) == string::npos) {
2858 dir = path.substr (0, slash+1);
2860 /* '-' is not a legal character for the NAME part of the path */
2862 if ((dash = path.find_last_of ('-')) == string::npos) {
2866 suffix = path.substr (dash+1);
2868 // Suffix is now everything after the dash. Now we need to eliminate
2869 // the nnnnn part, which is done by either finding a '%' or a '.'
2871 postfix = suffix.find_last_of ("%");
2872 if (postfix == string::npos) {
2873 postfix = suffix.find_last_of ('.');
2876 if (postfix != string::npos) {
2877 suffix = suffix.substr (postfix);
2879 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2883 const uint32_t limit = 10000;
2884 char buf[PATH_MAX+1];
2886 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2888 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2890 if (access (buf, F_OK) != 0) {
2898 error << "FATAL ERROR! Could not find a " << endl;
2907 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2911 char buf[PATH_MAX+1];
2912 const uint32_t limit = 10000;
2916 legalized = legalize_for_path (name);
2918 /* find a "version" of the file name that doesn't exist in
2919 any of the possible directories.
2922 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2924 vector<space_and_path>::iterator i;
2925 uint32_t existing = 0;
2927 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2932 spath += tape_dir_name;
2934 spath += sound_dir_name;
2939 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2940 } else if (nchan == 2) {
2942 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2944 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2946 } else if (nchan < 26) {
2947 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2949 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2957 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2958 } else if (nchan == 2) {
2960 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2962 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2964 } else if (nchan < 26) {
2965 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2967 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2971 if (access (buf, F_OK) == 0) {
2976 if (existing == 0) {
2981 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2982 throw failed_constructor();
2986 /* we now have a unique name for the file, but figure out where to
2993 spath = tape_dir ();
2995 spath = discover_best_sound_dir ();
2998 string::size_type pos = foo.find_last_of ('/');
3000 if (pos == string::npos) {
3003 spath += foo.substr (pos + 1);
3010 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3012 string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
3014 /* this might throw failed_constructor(), which is OK */
3017 return new DestructiveFileSource (spath,
3018 Config->get_native_file_data_format(),
3019 Config->get_native_file_header_format(),
3022 return new SndFileSource (spath,
3023 Config->get_native_file_data_format(),
3024 Config->get_native_file_header_format(),
3029 /* Playlist management */
3032 Session::playlist_by_name (string name)
3034 Glib::Mutex::Lock lm (playlist_lock);
3035 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3036 if ((*i)->name() == name) {
3040 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3041 if ((*i)->name() == name) {
3049 Session::add_playlist (Playlist* playlist)
3051 if (playlist->hidden()) {
3056 Glib::Mutex::Lock lm (playlist_lock);
3057 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3058 playlists.insert (playlists.begin(), playlist);
3060 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3061 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
3067 PlaylistAdded (playlist); /* EMIT SIGNAL */
3071 Session::track_playlist (Playlist* pl, bool inuse)
3073 PlaylistList::iterator x;
3076 Glib::Mutex::Lock lm (playlist_lock);
3079 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3081 unused_playlists.insert (pl);
3083 if ((x = playlists.find (pl)) != playlists.end()) {
3084 playlists.erase (x);
3089 //cerr << "shifting playlist to used: " << pl->name() << endl;
3091 playlists.insert (pl);
3093 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3094 unused_playlists.erase (x);
3101 Session::remove_playlist (Playlist* playlist)
3103 if (_state_of_the_state & Deletion) {
3108 Glib::Mutex::Lock lm (playlist_lock);
3109 // cerr << "removing playlist: " << playlist->name() << endl;
3111 PlaylistList::iterator i;
3113 i = find (playlists.begin(), playlists.end(), playlist);
3115 if (i != playlists.end()) {
3116 playlists.erase (i);
3119 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3120 if (i != unused_playlists.end()) {
3121 unused_playlists.erase (i);
3128 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3132 Session::set_audition (boost::shared_ptr<AudioRegion> r)
3134 pending_audition_region = r;
3135 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3136 schedule_butler_transport_work ();
3140 Session::non_realtime_set_audition ()
3142 if (pending_audition_region.get() == (AudioRegion*) 0xfeedface) {
3143 auditioner->audition_current_playlist ();
3144 } else if (pending_audition_region) {
3145 auditioner->audition_region (pending_audition_region);
3147 pending_audition_region.reset ((AudioRegion*) 0);
3148 AuditionActive (true); /* EMIT SIGNAL */
3152 Session::audition_playlist ()
3154 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3155 ev->set_ptr ((void*) 0xfeedface);
3160 Session::audition_region (boost::shared_ptr<Region> r)
3162 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
3164 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3165 // ev->set_ptr (ar); // AUDFIX
3171 Session::cancel_audition ()
3173 if (auditioner->active()) {
3174 auditioner->cancel_audition ();
3175 AuditionActive (false); /* EMIT SIGNAL */
3180 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3182 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3186 Session::remove_empty_sounds ()
3189 PathScanner scanner;
3194 vector<string *>* possible_audiofiles = scanner (dir, "\\.wav$", false, true);
3196 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3198 if (AudioFileSource::is_empty (*(*i))) {
3200 unlink ((*i)->c_str());
3202 string peak_path = peak_path_from_audio_path (**i);
3203 unlink (peak_path.c_str());
3209 delete possible_audiofiles;
3213 Session::is_auditioning () const
3215 /* can be called before we have an auditioner object */
3217 return auditioner->active();
3224 Session::set_all_solo (bool yn)
3226 shared_ptr<RouteList> r = routes.reader ();
3228 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3229 if (!(*i)->hidden()) {
3230 (*i)->set_solo (yn, this);
3238 Session::set_all_mute (bool yn)
3240 shared_ptr<RouteList> r = routes.reader ();
3242 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3243 if (!(*i)->hidden()) {
3244 (*i)->set_mute (yn, this);
3252 Session::n_diskstreams () const
3256 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3258 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3259 if (!(*i)->hidden()) {
3267 Session::graph_reordered ()
3269 /* don't do this stuff if we are setting up connections
3270 from a set_state() call.
3273 if (_state_of_the_state & InitialConnecting) {
3279 /* force all diskstreams to update their capture offset values to
3280 reflect any changes in latencies within the graph.
3283 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3285 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3286 (*i)->set_capture_offset ();
3291 Session::record_disenable_all ()
3293 record_enable_change_all (false);
3297 Session::record_enable_all ()
3299 record_enable_change_all (true);
3303 Session::record_enable_change_all (bool yn)
3305 shared_ptr<RouteList> r = routes.reader ();
3307 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3310 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3311 at->set_record_enable (yn, this);
3315 /* since we don't keep rec-enable state, don't mark session dirty */
3319 Session::add_redirect (Redirect* redirect)
3323 PortInsert* port_insert;
3324 PluginInsert* plugin_insert;
3326 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3327 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3328 _port_inserts.insert (_port_inserts.begin(), port_insert);
3329 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3330 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3332 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3335 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3336 _sends.insert (_sends.begin(), send);
3338 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3342 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3348 Session::remove_redirect (Redirect* redirect)
3352 PortInsert* port_insert;
3353 PluginInsert* plugin_insert;
3355 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3356 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3357 _port_inserts.remove (port_insert);
3358 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3359 _plugin_inserts.remove (plugin_insert);
3361 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3364 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3365 _sends.remove (send);
3367 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3375 Session::available_capture_duration ()
3377 const double scale = 4096.0 / sizeof (Sample);
3379 if (_total_free_4k_blocks * scale > (double) max_frames) {
3383 return (jack_nframes_t) floor (_total_free_4k_blocks * scale);
3387 Session::add_connection (ARDOUR::Connection* connection)
3390 Glib::Mutex::Lock guard (connection_lock);
3391 _connections.push_back (connection);
3394 ConnectionAdded (connection); /* EMIT SIGNAL */
3400 Session::remove_connection (ARDOUR::Connection* connection)
3402 bool removed = false;
3405 Glib::Mutex::Lock guard (connection_lock);
3406 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3408 if (i != _connections.end()) {
3409 _connections.erase (i);
3415 ConnectionRemoved (connection); /* EMIT SIGNAL */
3421 ARDOUR::Connection *
3422 Session::connection_by_name (string name) const
3424 Glib::Mutex::Lock lm (connection_lock);
3426 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3427 if ((*i)->name() == name) {
3436 Session::set_edit_mode (EditMode mode)
3441 Glib::Mutex::Lock lm (playlist_lock);
3443 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3444 (*i)->set_edit_mode (mode);
3449 ControlChanged (EditingMode); /* EMIT SIGNAL */
3453 Session::tempo_map_changed (Change ignored)
3460 Session::ensure_passthru_buffers (uint32_t howmany)
3462 while (howmany > _passthru_buffers.size()) {
3464 #ifdef NO_POSIX_MEMALIGN
3465 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3467 posix_memalign((void **)&p,16,current_block_size * 4);
3469 _passthru_buffers.push_back (p);
3473 #ifdef NO_POSIX_MEMALIGN
3474 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3476 posix_memalign((void **)&p,16,current_block_size * 4);
3478 memset (p, 0, sizeof (Sample) * current_block_size);
3479 _silent_buffers.push_back (p);
3483 #ifdef NO_POSIX_MEMALIGN
3484 p = (Sample *) malloc(current_block_size * sizeof(Sample));
3486 posix_memalign((void **)&p,16,current_block_size * 4);
3488 memset (p, 0, sizeof (Sample) * current_block_size);
3489 _send_buffers.push_back (p);
3492 allocate_pan_automation_buffers (current_block_size, howmany, false);
3496 Session::next_send_name ()
3499 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3504 Session::next_insert_name ()
3507 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3511 /* Named Selection management */
3514 Session::named_selection_by_name (string name)
3516 Glib::Mutex::Lock lm (named_selection_lock);
3517 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3518 if ((*i)->name == name) {
3526 Session::add_named_selection (NamedSelection* named_selection)
3529 Glib::Mutex::Lock lm (named_selection_lock);
3530 named_selections.insert (named_selections.begin(), named_selection);
3535 NamedSelectionAdded (); /* EMIT SIGNAL */
3539 Session::remove_named_selection (NamedSelection* named_selection)
3541 bool removed = false;
3544 Glib::Mutex::Lock lm (named_selection_lock);
3546 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3548 if (i != named_selections.end()) {
3550 named_selections.erase (i);
3557 NamedSelectionRemoved (); /* EMIT SIGNAL */
3562 Session::reset_native_file_format ()
3564 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3566 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3567 (*i)->reset_write_sources (false);
3572 Session::route_name_unique (string n) const
3574 shared_ptr<RouteList> r = routes.reader ();
3576 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3577 if ((*i)->name() == n) {
3586 Session::cleanup_audio_file_source (AudioFileSource& fs)
3588 return fs.move_to_trash (dead_sound_dir_name);
3592 Session::n_playlists () const
3594 Glib::Mutex::Lock lm (playlist_lock);
3595 return playlists.size();
3599 Session::set_solo_model (SoloModel sm)
3601 if (sm != _solo_model) {
3603 ControlChanged (SoloingModel);
3609 Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force)
3611 if (!force && howmany <= _npan_buffers) {
3615 if (_pan_automation_buffer) {
3617 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3618 delete [] _pan_automation_buffer[i];
3621 delete [] _pan_automation_buffer;
3624 _pan_automation_buffer = new pan_t*[howmany];
3626 for (uint32_t i = 0; i < howmany; ++i) {
3627 _pan_automation_buffer[i] = new pan_t[nframes];
3630 _npan_buffers = howmany;
3634 Session::freeze (InterThreadInfo& itt)
3636 shared_ptr<RouteList> r = routes.reader ();
3638 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3642 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
3643 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3654 Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
3655 bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
3659 AudioFileSource* fsource;
3661 char buf[PATH_MAX+1];
3664 jack_nframes_t position;
3665 jack_nframes_t this_chunk;
3666 jack_nframes_t to_do;
3667 vector<Sample*> buffers;
3669 // any bigger than this seems to cause stack overflows in called functions
3670 const jack_nframes_t chunk_size = (128 * 1024)/4;
3672 g_atomic_int_set (&processing_prohibited, 1);
3674 /* call tree *MUST* hold route_lock */
3676 if ((playlist = track.diskstream()->playlist()) == 0) {
3680 /* external redirects will be a problem */
3682 if (track.has_external_redirects()) {
3686 nchans = track.audio_diskstream()->n_channels();
3688 dir = discover_best_sound_dir ();
3690 for (uint32_t chan_n=0; chan_n < nchans; ++chan_n) {
3692 for (x = 0; x < 99999; ++x) {
3693 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3694 if (access (buf, F_OK) != 0) {
3700 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3705 fsource = new SndFileSource (buf,
3706 Config->get_native_file_data_format(),
3707 Config->get_native_file_header_format(),
3712 catch (failed_constructor& err) {
3713 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3717 srcs.push_back(fsource);
3720 /* XXX need to flush all redirects */
3725 /* create a set of reasonably-sized buffers */
3727 for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
3729 #ifdef NO_POSIX_MEMALIGN
3730 b = (Sample *) malloc(chunk_size * sizeof(Sample));
3732 posix_memalign((void **)&b,16,chunk_size * 4);
3734 buffers.push_back (b);
3737 while (to_do && !itt.cancel) {
3739 this_chunk = min (to_do, chunk_size);
3741 if (track.export_stuff (buffers, nchans, start, this_chunk)) {
3746 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3747 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3750 if (afs->write (buffers[n], this_chunk) != this_chunk) {
3756 start += this_chunk;
3757 to_do -= this_chunk;
3759 itt.progress = (float) (1.0 - ((double) to_do / len));
3768 xnow = localtime (&now);
3770 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3771 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3773 afs->update_header (position, *xnow, now);
3777 /* build peakfile for new source */
3779 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3780 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3782 afs->build_peaks ();
3791 for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3792 AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
3794 afs->mark_for_remove ();
3800 for (vector<Sample*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
3804 g_atomic_int_set (&processing_prohibited, 0);
3812 Session::get_silent_buffers (uint32_t howmany)
3814 for (uint32_t i = 0; i < howmany; ++i) {
3815 memset (_silent_buffers[i], 0, sizeof (Sample) * current_block_size);
3817 return _silent_buffers;
3821 Session::ntracks () const
3824 shared_ptr<RouteList> r = routes.reader ();
3826 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3827 if (dynamic_cast<AudioTrack*> ((*i).get())) {
3836 Session::nbusses () const
3839 shared_ptr<RouteList> r = routes.reader ();
3841 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3842 if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
3851 Session::set_layer_model (LayerModel lm)
3853 if (lm != layer_model) {
3856 ControlChanged (LayeringModel);
3861 Session::set_xfade_model (CrossfadeModel xm)
3863 if (xm != xfade_model) {
3866 ControlChanged (CrossfadingModel);
3871 Session::add_curve(Curve *curve)
3873 curves[curve->id()] = curve;
3877 Session::add_automation_list(AutomationList *al)
3879 automation_lists[al->id()] = al;