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/utils.h>
48 #include <ardour/audio_diskstream.h>
49 #include <ardour/audioplaylist.h>
50 #include <ardour/audioregion.h>
51 #include <ardour/audiofilesource.h>
52 #include <ardour/midi_diskstream.h>
53 #include <ardour/midi_playlist.h>
54 #include <ardour/midi_region.h>
55 #include <ardour/smf_source.h>
56 #include <ardour/destructive_filesource.h>
57 #include <ardour/auditioner.h>
58 #include <ardour/recent_sessions.h>
59 #include <ardour/redirect.h>
60 #include <ardour/send.h>
61 #include <ardour/insert.h>
62 #include <ardour/connection.h>
63 #include <ardour/slave.h>
64 #include <ardour/tempo.h>
65 #include <ardour/audio_track.h>
66 #include <ardour/midi_track.h>
67 #include <ardour/cycle_timer.h>
68 #include <ardour/named_selection.h>
69 #include <ardour/crossfade.h>
70 #include <ardour/playlist.h>
71 #include <ardour/click.h>
72 #include <ardour/data_type.h>
73 #include <ardour/buffer_set.h>
74 #include <ardour/source_factory.h>
75 #include <ardour/region_factory.h>
78 #include <ardour/osc.h>
84 using namespace ARDOUR;
86 using boost::shared_ptr;
88 const char* Session::_template_suffix = X_(".template");
89 const char* Session::_statefile_suffix = X_(".ardour");
90 const char* Session::_pending_suffix = X_(".pending");
91 const char* Session::old_sound_dir_name = X_("sounds");
92 const char* Session::sound_dir_name = X_("audiofiles");
93 const char* Session::peak_dir_name = X_("peaks");
94 const char* Session::dead_sound_dir_name = X_("dead_sounds");
95 const char* Session::interchange_dir_name = X_("interchange");
97 Session::compute_peak_t Session::compute_peak = 0;
98 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
99 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
100 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
102 sigc::signal<int> Session::AskAboutPendingState;
103 sigc::signal<void> Session::SendFeedback;
105 sigc::signal<void> Session::SMPTEOffsetChanged;
106 sigc::signal<void> Session::StartTimeChanged;
107 sigc::signal<void> Session::EndTimeChanged;
110 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
113 char buf[PATH_MAX+1];
117 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
118 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
124 /* check to see if it exists, and what it is */
126 if (stat (str.c_str(), &statbuf)) {
127 if (errno == ENOENT) {
130 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
138 /* it exists, so it must either be the name
139 of the directory, or the name of the statefile
143 if (S_ISDIR (statbuf.st_mode)) {
145 string::size_type slash = str.find_last_of ('/');
147 if (slash == string::npos) {
149 /* a subdirectory of cwd, so statefile should be ... */
155 tmp += _statefile_suffix;
159 if (stat (tmp.c_str(), &statbuf)) {
160 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
170 /* some directory someplace in the filesystem.
171 the snapshot name is the directory name
176 snapshot = str.substr (slash+1);
180 } else if (S_ISREG (statbuf.st_mode)) {
182 string::size_type slash = str.find_last_of ('/');
183 string::size_type suffix;
185 /* remove the suffix */
187 if (slash != string::npos) {
188 snapshot = str.substr (slash+1);
193 suffix = snapshot.find (_statefile_suffix);
195 if (suffix == string::npos) {
196 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
202 snapshot = snapshot.substr (0, suffix);
204 if (slash == string::npos) {
206 /* we must be in the directory where the
207 statefile lives. get it using cwd().
210 char cwd[PATH_MAX+1];
212 if (getcwd (cwd, sizeof (cwd)) == 0) {
213 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
222 /* full path to the statefile */
224 path = str.substr (0, slash);
229 /* what type of file is it? */
230 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
236 /* its the name of a new directory. get the name
240 string::size_type slash = str.find_last_of ('/');
242 if (slash == string::npos) {
244 /* no slash, just use the name, but clean it up */
246 path = legalize_for_path (str);
252 snapshot = str.substr (slash+1);
259 Session::Session (AudioEngine &eng,
261 string snapshot_name,
262 string* mix_template)
265 _scratch_buffers(new BufferSet()),
266 _silent_buffers(new BufferSet()),
267 _send_buffers(new BufferSet()),
268 _mmc_port (default_mmc_port),
269 _mtc_port (default_mtc_port),
270 _midi_port (default_midi_port),
271 pending_events (2048),
272 //midi_requests (128), // the size of this should match the midi request pool size
273 _send_smpte_update (false),
274 diskstreams (new DiskstreamList),
275 routes (new RouteList),
276 auditioner ((Auditioner*) 0),
282 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
284 n_physical_outputs = _engine.n_physical_outputs();
285 n_physical_inputs = _engine.n_physical_inputs();
287 first_stage_init (fullpath, snapshot_name);
289 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
291 if (create (new_session, mix_template, compute_initial_length())) {
292 cerr << "create failed\n";
293 throw failed_constructor ();
297 if (second_stage_init (new_session)) {
298 cerr << "2nd state failed\n";
299 throw failed_constructor ();
302 store_recent_sessions(_name, _path);
304 bool was_dirty = dirty();
306 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
308 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
311 DirtyChanged (); /* EMIT SIGNAL */
315 Session::Session (AudioEngine &eng,
317 string snapshot_name,
318 AutoConnectOption input_ac,
319 AutoConnectOption output_ac,
320 uint32_t control_out_channels,
321 uint32_t master_out_channels,
322 uint32_t requested_physical_in,
323 uint32_t requested_physical_out,
324 nframes_t initial_length)
327 _scratch_buffers(new BufferSet()),
328 _silent_buffers(new BufferSet()),
329 _send_buffers(new BufferSet()),
330 _mmc_port (default_mmc_port),
331 _mtc_port (default_mtc_port),
332 _midi_port (default_midi_port),
333 pending_events (2048),
334 //midi_requests (16),
335 _send_smpte_update (false),
336 diskstreams (new DiskstreamList),
337 routes (new RouteList),
343 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
345 n_physical_outputs = _engine.n_physical_outputs();
346 n_physical_inputs = _engine.n_physical_inputs();
348 if (n_physical_inputs) {
349 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
352 if (n_physical_outputs) {
353 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
356 first_stage_init (fullpath, snapshot_name);
358 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
361 if (create (new_session, 0, initial_length)) {
362 throw failed_constructor ();
366 if (control_out_channels) {
367 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
374 if (master_out_channels) {
375 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
381 /* prohibit auto-connect to master, because there isn't one */
382 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
385 Config->set_input_auto_connect (input_ac);
386 Config->set_output_auto_connect (output_ac);
388 if (second_stage_init (new_session)) {
389 throw failed_constructor ();
392 store_recent_sessions(_name, _path);
394 bool was_dirty = dirty ();
396 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
399 DirtyChanged (); /* EMIT SIGNAL */
405 /* if we got to here, leaving pending capture state around
409 remove_pending_capture_state ();
411 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
412 _engine.remove_session ();
414 GoingAway (); /* EMIT SIGNAL */
420 /* clear history so that no references to objects are held any more */
424 /* clear state tree so that no references to objects are held any more */
430 terminate_butler_thread ();
431 //terminate_midi_thread ();
433 if (click_data && click_data != default_click) {
434 delete [] click_data;
437 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
438 delete [] click_emphasis_data;
443 delete _scratch_buffers;
444 delete _silent_buffers;
445 delete _send_buffers;
447 AudioDiskstream::free_working_buffers();
449 #undef TRACK_DESTRUCTION
450 #ifdef TRACK_DESTRUCTION
451 cerr << "delete named selections\n";
452 #endif /* TRACK_DESTRUCTION */
453 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
454 NamedSelectionList::iterator tmp;
463 #ifdef TRACK_DESTRUCTION
464 cerr << "delete playlists\n";
465 #endif /* TRACK_DESTRUCTION */
466 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
467 PlaylistList::iterator tmp;
477 #ifdef TRACK_DESTRUCTION
478 cerr << "delete regions\n";
479 #endif /* TRACK_DESTRUCTION */
481 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
482 RegionList::iterator tmp;
487 cerr << "dropping refs on a region (" << i->second->name() << " @ " << i->second << ") with UC = " << i->second.use_count() << endl;
488 i->second->drop_references ();
489 cerr << "AFTER: UC = " << i->second.use_count() << endl;
496 #ifdef TRACK_DESTRUCTION
497 cerr << "delete routes\n";
498 #endif /* TRACK_DESTRUCTION */
500 RCUWriter<RouteList> writer (routes);
501 boost::shared_ptr<RouteList> r = writer.get_copy ();
502 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
503 (*i)->drop_references ();
506 /* writer goes out of scope and updates master */
511 #ifdef TRACK_DESTRUCTION
512 cerr << "delete diskstreams\n";
513 #endif /* TRACK_DESTRUCTION */
515 RCUWriter<DiskstreamList> dwriter (diskstreams);
516 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
517 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
518 (*i)->drop_references ();
522 diskstreams.flush ();
524 #ifdef TRACK_DESTRUCTION
525 cerr << "delete audio sources\n";
526 #endif /* TRACK_DESTRUCTION */
527 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
528 SourceMap::iterator tmp;
533 i->second->drop_references ();
540 #ifdef TRACK_DESTRUCTION
541 cerr << "delete mix groups\n";
542 #endif /* TRACK_DESTRUCTION */
543 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
544 list<RouteGroup*>::iterator tmp;
554 #ifdef TRACK_DESTRUCTION
555 cerr << "delete edit groups\n";
556 #endif /* TRACK_DESTRUCTION */
557 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
558 list<RouteGroup*>::iterator tmp;
568 #ifdef TRACK_DESTRUCTION
569 cerr << "delete connections\n";
570 #endif /* TRACK_DESTRUCTION */
571 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
572 ConnectionList::iterator tmp;
582 if (butler_mixdown_buffer) {
583 delete [] butler_mixdown_buffer;
586 if (butler_gain_buffer) {
587 delete [] butler_gain_buffer;
590 Crossfade::set_buffer_size (0);
598 Session::set_worst_io_latencies ()
600 _worst_output_latency = 0;
601 _worst_input_latency = 0;
603 if (!_engine.connected()) {
607 boost::shared_ptr<RouteList> r = routes.reader ();
609 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
610 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
611 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
616 Session::when_engine_running ()
618 string first_physical_output;
620 /* we don't want to run execute this again */
622 first_time_running.disconnect ();
624 set_block_size (_engine.frames_per_cycle());
625 set_frame_rate (_engine.frame_rate());
627 Config->map_parameters (mem_fun (*this, &Session::config_changed));
629 /* every time we reconnect, recompute worst case output latencies */
631 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
633 if (synced_to_jack()) {
634 _engine.transport_stop ();
637 if (Config->get_jack_time_master()) {
638 _engine.transport_locate (_transport_frame);
646 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
648 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
650 /* existing state for Click */
652 if (_click_io->set_state (*child->children().front()) == 0) {
654 _clicking = Config->get_clicking ();
658 error << _("could not setup Click I/O") << endmsg;
664 /* default state for Click */
666 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
668 if (first_physical_output.length()) {
669 if (_click_io->add_output_port (first_physical_output, this)) {
670 // relax, even though its an error
672 _clicking = Config->get_clicking ();
678 catch (failed_constructor& err) {
679 error << _("cannot setup Click I/O") << endmsg;
682 set_worst_io_latencies ();
685 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
688 if (auditioner == 0) {
690 /* we delay creating the auditioner till now because
691 it makes its own connections to ports named
692 in the ARDOUR_RC config file. the engine has
693 to be running for this to work.
697 auditioner.reset (new Auditioner (*this));
700 catch (failed_constructor& err) {
701 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
705 /* Create a set of Connection objects that map
706 to the physical outputs currently available
711 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
713 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
715 Connection* c = new OutputConnection (buf, true);
718 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
723 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
725 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
727 Connection* c = new InputConnection (buf, true);
730 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
737 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
739 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
741 Connection* c = new OutputConnection (buf, true);
745 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
746 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
751 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
753 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
755 Connection* c = new InputConnection (buf, true);
759 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
760 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
769 /* create master/control ports */
774 /* force the master to ignore any later call to this */
776 if (_master_out->pending_state_node) {
777 _master_out->ports_became_legal();
780 /* no panner resets till we are through */
782 _master_out->defer_pan_reset ();
784 while (_master_out->n_inputs().get(DataType::AUDIO)
785 < _master_out->input_maximum().get(DataType::AUDIO)) {
786 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
787 error << _("cannot setup master inputs")
793 while (_master_out->n_outputs().get(DataType::AUDIO)
794 < _master_out->output_maximum().get(DataType::AUDIO)) {
795 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
796 error << _("cannot setup master outputs")
803 _master_out->allow_pan_reset ();
807 Connection* c = new OutputConnection (_("Master Out"), true);
809 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
811 c->add_connection ((int) n, _master_out->input(n)->name());
818 /* catch up on send+insert cnts */
822 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
825 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
826 if (id > insert_cnt) {
834 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
837 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
844 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
846 /* hook us up to the engine */
848 _engine.set_session (this);
853 osc->set_session (*this);
856 _state_of_the_state = Clean;
858 DirtyChanged (); /* EMIT SIGNAL */
862 Session::hookup_io ()
864 /* stop graph reordering notifications from
865 causing resorts, etc.
868 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
870 /* Tell all IO objects to create their ports */
877 while (_control_out->n_inputs().get(DataType::AUDIO) < _control_out->input_maximum().get(DataType::AUDIO)) {
878 if (_control_out->add_input_port ("", this)) {
879 error << _("cannot setup control inputs")
885 while (_control_out->n_outputs().get(DataType::AUDIO) < _control_out->output_maximum().get(DataType::AUDIO)) {
886 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
887 error << _("cannot set up master outputs")
895 /* Tell all IO objects to connect themselves together */
897 IO::enable_connecting ();
899 /* Now reset all panners */
901 IO::reset_panners ();
903 /* Anyone who cares about input state, wake up and do something */
905 IOConnectionsComplete (); /* EMIT SIGNAL */
907 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
909 /* now handle the whole enchilada as if it was one
915 /* update mixer solo state */
921 Session::playlist_length_changed (Playlist* pl)
923 /* we can't just increase end_location->end() if pl->get_maximum_extent()
924 if larger. if the playlist used to be the longest playlist,
925 and its now shorter, we have to decrease end_location->end(). hence,
926 we have to iterate over all diskstreams and check the
927 playlists currently in use.
933 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
937 if ((playlist = dstream->playlist()) != 0) {
938 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
941 /* see comment in playlist_length_changed () */
946 Session::record_enabling_legal () const
948 /* this used to be in here, but survey says.... we don't need to restrict it */
949 // if (record_status() == Recording) {
953 if (Config->get_all_safe()) {
960 Session::reset_input_monitor_state ()
962 if (transport_rolling()) {
964 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
966 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
967 if ((*i)->record_enabled ()) {
968 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
969 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
973 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
975 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
976 if ((*i)->record_enabled ()) {
977 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
978 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
985 Session::auto_punch_start_changed (Location* location)
987 replace_event (Event::PunchIn, location->start());
989 if (get_record_enabled() && Config->get_punch_in()) {
990 /* capture start has been changed, so save new pending state */
991 save_state ("", true);
996 Session::auto_punch_end_changed (Location* location)
998 nframes_t when_to_stop = location->end();
999 // when_to_stop += _worst_output_latency + _worst_input_latency;
1000 replace_event (Event::PunchOut, when_to_stop);
1004 Session::auto_punch_changed (Location* location)
1006 nframes_t when_to_stop = location->end();
1008 replace_event (Event::PunchIn, location->start());
1009 //when_to_stop += _worst_output_latency + _worst_input_latency;
1010 replace_event (Event::PunchOut, when_to_stop);
1014 Session::auto_loop_changed (Location* location)
1016 replace_event (Event::AutoLoop, location->end(), location->start());
1018 if (transport_rolling() && play_loop) {
1020 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1022 if (_transport_frame > location->end()) {
1023 // relocate to beginning of loop
1024 clear_events (Event::LocateRoll);
1026 request_locate (location->start(), true);
1029 else if (Config->get_seamless_loop() && !loop_changing) {
1031 // schedule a locate-roll to refill the diskstreams at the
1032 // previous loop end
1033 loop_changing = true;
1035 if (location->end() > last_loopend) {
1036 clear_events (Event::LocateRoll);
1037 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1044 last_loopend = location->end();
1049 Session::set_auto_punch_location (Location* location)
1053 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1054 auto_punch_start_changed_connection.disconnect();
1055 auto_punch_end_changed_connection.disconnect();
1056 auto_punch_changed_connection.disconnect();
1057 existing->set_auto_punch (false, this);
1058 remove_event (existing->start(), Event::PunchIn);
1059 clear_events (Event::PunchOut);
1060 auto_punch_location_changed (0);
1065 if (location == 0) {
1069 if (location->end() <= location->start()) {
1070 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1074 auto_punch_start_changed_connection.disconnect();
1075 auto_punch_end_changed_connection.disconnect();
1076 auto_punch_changed_connection.disconnect();
1078 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1079 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1080 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1082 location->set_auto_punch (true, this);
1083 auto_punch_location_changed (location);
1087 Session::set_auto_loop_location (Location* location)
1091 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1092 auto_loop_start_changed_connection.disconnect();
1093 auto_loop_end_changed_connection.disconnect();
1094 auto_loop_changed_connection.disconnect();
1095 existing->set_auto_loop (false, this);
1096 remove_event (existing->end(), Event::AutoLoop);
1097 auto_loop_location_changed (0);
1102 if (location == 0) {
1106 if (location->end() <= location->start()) {
1107 error << _("Session: you can't use a mark for auto loop") << endmsg;
1111 last_loopend = location->end();
1113 auto_loop_start_changed_connection.disconnect();
1114 auto_loop_end_changed_connection.disconnect();
1115 auto_loop_changed_connection.disconnect();
1117 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1118 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1119 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1121 location->set_auto_loop (true, this);
1122 auto_loop_location_changed (location);
1126 Session::locations_added (Location* ignored)
1132 Session::locations_changed ()
1134 _locations.apply (*this, &Session::handle_locations_changed);
1138 Session::handle_locations_changed (Locations::LocationList& locations)
1140 Locations::LocationList::iterator i;
1142 bool set_loop = false;
1143 bool set_punch = false;
1145 for (i = locations.begin(); i != locations.end(); ++i) {
1149 if (location->is_auto_punch()) {
1150 set_auto_punch_location (location);
1153 if (location->is_auto_loop()) {
1154 set_auto_loop_location (location);
1161 set_auto_loop_location (0);
1164 set_auto_punch_location (0);
1171 Session::enable_record ()
1173 /* XXX really atomic compare+swap here */
1174 if (g_atomic_int_get (&_record_status) != Recording) {
1175 g_atomic_int_set (&_record_status, Recording);
1176 _last_record_location = _transport_frame;
1177 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1179 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1180 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1181 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1182 if ((*i)->record_enabled ()) {
1183 (*i)->monitor_input (true);
1188 RecordStateChanged ();
1193 Session::disable_record (bool rt_context, bool force)
1197 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1199 if (!Config->get_latched_record_enable () || force) {
1200 g_atomic_int_set (&_record_status, Disabled);
1202 if (rs == Recording) {
1203 g_atomic_int_set (&_record_status, Enabled);
1207 // FIXME: timestamp correct? [DR]
1208 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1209 // does this /need/ to be sent in all cases?
1211 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1213 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1214 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1216 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1217 if ((*i)->record_enabled ()) {
1218 (*i)->monitor_input (false);
1223 RecordStateChanged (); /* emit signal */
1226 remove_pending_capture_state ();
1232 Session::step_back_from_record ()
1234 g_atomic_int_set (&_record_status, Enabled);
1236 if (Config->get_monitoring_model() == HardwareMonitoring) {
1237 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1239 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1240 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1241 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1242 (*i)->monitor_input (false);
1249 Session::maybe_enable_record ()
1251 g_atomic_int_set (&_record_status, Enabled);
1253 /* this function is currently called from somewhere other than an RT thread.
1254 this save_state() call therefore doesn't impact anything.
1257 save_state ("", true);
1259 if (_transport_speed) {
1260 if (!Config->get_punch_in()) {
1264 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1265 RecordStateChanged (); /* EMIT SIGNAL */
1272 Session::audible_frame () const
1278 /* the first of these two possible settings for "offset"
1279 mean that the audible frame is stationary until
1280 audio emerges from the latency compensation
1283 the second means that the audible frame is stationary
1284 until audio would emerge from a physical port
1285 in the absence of any plugin latency compensation
1288 offset = _worst_output_latency;
1290 if (offset > current_block_size) {
1291 offset -= current_block_size;
1293 /* XXX is this correct? if we have no external
1294 physical connections and everything is internal
1295 then surely this is zero? still, how
1296 likely is that anyway?
1298 offset = current_block_size;
1301 if (synced_to_jack()) {
1302 tf = _engine.transport_frame();
1304 tf = _transport_frame;
1307 if (_transport_speed == 0) {
1317 if (!non_realtime_work_pending()) {
1321 /* take latency into account */
1330 Session::set_frame_rate (nframes_t frames_per_second)
1332 /** \fn void Session::set_frame_size(nframes_t)
1333 the AudioEngine object that calls this guarantees
1334 that it will not be called while we are also in
1335 ::process(). Its fine to do things that block
1339 _base_frame_rate = frames_per_second;
1343 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1345 // XXX we need some equivalent to this, somehow
1346 // SndFileSource::setup_standard_crossfades (frames_per_second);
1350 /* XXX need to reset/reinstantiate all LADSPA plugins */
1354 Session::set_block_size (nframes_t nframes)
1356 /* the AudioEngine guarantees
1357 that it will not be called while we are also in
1358 ::process(). It is therefore fine to do things that block
1364 current_block_size = nframes;
1366 ensure_buffers(_scratch_buffers->available());
1368 if (_gain_automation_buffer) {
1369 delete [] _gain_automation_buffer;
1371 _gain_automation_buffer = new gain_t[nframes];
1373 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1375 boost::shared_ptr<RouteList> r = routes.reader ();
1377 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1378 (*i)->set_block_size (nframes);
1381 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1382 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1383 (*i)->set_block_size (nframes);
1386 set_worst_io_latencies ();
1391 Session::set_default_fade (float steepness, float fade_msecs)
1394 nframes_t fade_frames;
1396 /* Don't allow fade of less 1 frame */
1398 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1405 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1409 default_fade_msecs = fade_msecs;
1410 default_fade_steepness = steepness;
1413 // jlc, WTF is this!
1414 Glib::RWLock::ReaderLock lm (route_lock);
1415 AudioRegion::set_default_fade (steepness, fade_frames);
1420 /* XXX have to do this at some point */
1421 /* foreach region using default fade, reset, then
1422 refill_all_diskstream_buffers ();
1427 struct RouteSorter {
1428 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1429 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1431 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1434 if (r1->fed_by.empty()) {
1435 if (r2->fed_by.empty()) {
1436 /* no ardour-based connections inbound to either route. just use signal order */
1437 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1439 /* r2 has connections, r1 does not; run r1 early */
1443 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1450 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1452 shared_ptr<Route> r2;
1454 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1455 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1459 /* make a copy of the existing list of routes that feed r1 */
1461 set<shared_ptr<Route> > existing = r1->fed_by;
1463 /* for each route that feeds r1, recurse, marking it as feeding
1467 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1470 /* r2 is a route that feeds r1 which somehow feeds base. mark
1471 base as being fed by r2
1474 rbase->fed_by.insert (r2);
1478 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1482 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1486 /* now recurse, so that we can mark base as being fed by
1487 all routes that feed r2
1490 trace_terminal (r2, rbase);
1497 Session::resort_routes ()
1499 /* don't do anything here with signals emitted
1500 by Routes while we are being destroyed.
1503 if (_state_of_the_state & Deletion) {
1510 RCUWriter<RouteList> writer (routes);
1511 shared_ptr<RouteList> r = writer.get_copy ();
1512 resort_routes_using (r);
1513 /* writer goes out of scope and forces update */
1518 Session::resort_routes_using (shared_ptr<RouteList> r)
1520 RouteList::iterator i, j;
1522 for (i = r->begin(); i != r->end(); ++i) {
1524 (*i)->fed_by.clear ();
1526 for (j = r->begin(); j != r->end(); ++j) {
1528 /* although routes can feed themselves, it will
1529 cause an endless recursive descent if we
1530 detect it. so don't bother checking for
1538 if ((*j)->feeds (*i)) {
1539 (*i)->fed_by.insert (*j);
1544 for (i = r->begin(); i != r->end(); ++i) {
1545 trace_terminal (*i, *i);
1552 cerr << "finished route resort\n";
1554 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1555 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1562 list<boost::shared_ptr<MidiTrack> >
1563 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1565 char track_name[32];
1566 uint32_t track_id = 0;
1568 uint32_t channels_used = 0;
1570 RouteList new_routes;
1571 list<boost::shared_ptr<MidiTrack> > ret;
1573 /* count existing midi tracks */
1576 shared_ptr<RouteList> r = routes.reader ();
1578 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1579 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1580 if (!(*i)->hidden()) {
1582 channels_used += (*i)->n_inputs().get(DataType::MIDI);
1590 /* check for duplicate route names, since we might have pre-existing
1591 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1592 save, close,restart,add new route - first named route is now
1600 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1602 if (route_by_name (track_name) == 0) {
1606 } while (track_id < (UINT_MAX-1));
1609 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1611 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1612 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1615 channels_used += track->n_inputs ().get(DataType::MIDI);
1617 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1618 track->set_remote_control_id (ntracks());
1620 new_routes.push_back (track);
1621 ret.push_back (track);
1624 catch (failed_constructor &err) {
1625 error << _("Session: could not create new midi track.") << endmsg;
1626 // XXX should we delete the tracks already created?
1634 if (!new_routes.empty()) {
1635 add_routes (new_routes, false);
1636 save_state (_current_snapshot_name);
1642 list<boost::shared_ptr<AudioTrack> >
1643 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1645 char track_name[32];
1646 uint32_t track_id = 0;
1648 uint32_t channels_used = 0;
1650 RouteList new_routes;
1651 list<boost::shared_ptr<AudioTrack> > ret;
1653 /* count existing audio tracks */
1656 shared_ptr<RouteList> r = routes.reader ();
1658 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1659 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1660 if (!(*i)->hidden()) {
1662 channels_used += (*i)->n_inputs().get(DataType::AUDIO);
1668 vector<string> physinputs;
1669 vector<string> physoutputs;
1670 uint32_t nphysical_in;
1671 uint32_t nphysical_out;
1673 _engine.get_physical_outputs (physoutputs);
1674 _engine.get_physical_inputs (physinputs);
1678 /* check for duplicate route names, since we might have pre-existing
1679 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1680 save, close,restart,add new route - first named route is now
1688 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1690 if (route_by_name (track_name) == 0) {
1694 } while (track_id < (UINT_MAX-1));
1696 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1697 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1702 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1703 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1709 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1711 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1712 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1713 input_channels, output_channels)
1718 for (uint32_t x = 0; x < track->n_inputs().get(DataType::AUDIO) && x < nphysical_in; ++x) {
1722 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1723 port = physinputs[(channels_used+x)%nphysical_in];
1726 if (port.length() && track->connect_input (track->input (x), port, this)) {
1732 for (uint32_t x = 0; x < track->n_outputs().get(DataType::MIDI); ++x) {
1736 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1737 port = physoutputs[(channels_used+x)%nphysical_out];
1738 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1740 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1744 if (port.length() && track->connect_output (track->output (x), port, this)) {
1749 channels_used += track->n_inputs ().get(DataType::AUDIO);
1752 vector<string> cports;
1753 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
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));
1763 track->set_remote_control_id (ntracks());
1765 new_routes.push_back (track);
1766 ret.push_back (track);
1769 catch (failed_constructor &err) {
1770 error << _("Session: could not create new audio track.") << endmsg;
1771 // XXX should we delete the tracks already created?
1779 if (!new_routes.empty()) {
1780 add_routes (new_routes, false);
1781 save_state (_current_snapshot_name);
1788 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1791 uint32_t bus_id = 1;
1796 /* count existing audio busses */
1799 shared_ptr<RouteList> r = routes.reader ();
1801 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1802 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1803 if (!(*i)->hidden()) {
1810 vector<string> physinputs;
1811 vector<string> physoutputs;
1813 _engine.get_physical_outputs (physoutputs);
1814 _engine.get_physical_inputs (physinputs);
1821 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1823 if (route_by_name (bus_name) == 0) {
1827 } while (bus_id < (UINT_MAX-1));
1830 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1832 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1833 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1834 input_channels, output_channels)
1838 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().get(DataType::AUDIO); ++x) {
1842 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1843 port = physinputs[((n+x)%n_physical_inputs)];
1846 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1851 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().get(DataType::AUDIO); ++x) {
1855 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1856 port = physoutputs[((n+x)%n_physical_outputs)];
1857 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1859 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1863 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1869 vector<string> cports;
1870 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1872 for (uint32_t n = 0; n < ni; ++n) {
1873 cports.push_back (_control_out->input(n)->name());
1875 bus->set_control_outs (cports);
1878 ret.push_back (bus);
1882 catch (failed_constructor &err) {
1883 error << _("Session: could not create new audio route.") << endmsg;
1892 add_routes (ret, false);
1893 save_state (_current_snapshot_name);
1901 Session::add_routes (RouteList& new_routes, bool save)
1904 RCUWriter<RouteList> writer (routes);
1905 shared_ptr<RouteList> r = writer.get_copy ();
1906 r->insert (r->end(), new_routes.begin(), new_routes.end());
1907 resort_routes_using (r);
1910 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1912 boost::weak_ptr<Route> wpr (*x);
1914 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1915 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1916 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1917 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1919 if ((*x)->master()) {
1923 if ((*x)->control()) {
1924 _control_out = (*x);
1931 save_state (_current_snapshot_name);
1934 RouteAdded (new_routes); /* EMIT SIGNAL */
1938 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1940 /* need to do this in case we're rolling at the time, to prevent false underruns */
1941 dstream->do_refill_with_alloc();
1944 RCUWriter<DiskstreamList> writer (diskstreams);
1945 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1946 ds->push_back (dstream);
1949 dstream->set_block_size (current_block_size);
1951 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1952 /* this will connect to future changes, and check the current length */
1953 diskstream_playlist_changed (dstream);
1955 dstream->prepare ();
1959 Session::remove_route (shared_ptr<Route> route)
1962 RCUWriter<RouteList> writer (routes);
1963 shared_ptr<RouteList> rs = writer.get_copy ();
1967 /* deleting the master out seems like a dumb
1968 idea, but its more of a UI policy issue
1972 if (route == _master_out) {
1973 _master_out = shared_ptr<Route> ();
1976 if (route == _control_out) {
1977 _control_out = shared_ptr<Route> ();
1979 /* cancel control outs for all routes */
1981 vector<string> empty;
1983 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1984 (*r)->set_control_outs (empty);
1988 update_route_solo_state ();
1990 /* writer goes out of scope, forces route list update */
1994 boost::shared_ptr<Diskstream> ds;
1996 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
1997 ds = t->diskstream();
2003 RCUWriter<DiskstreamList> dsl (diskstreams);
2004 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2009 find_current_end ();
2011 update_latency_compensation (false, false);
2014 // We need to disconnect the routes inputs and outputs
2015 route->disconnect_inputs(NULL);
2016 route->disconnect_outputs(NULL);
2018 /* get rid of it from the dead wood collection in the route list manager */
2020 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2024 /* try to cause everyone to drop their references */
2026 route->drop_references ();
2028 /* save the new state of the world */
2030 if (save_state (_current_snapshot_name)) {
2031 save_history (_current_snapshot_name);
2036 Session::route_mute_changed (void* src)
2042 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2044 if (solo_update_disabled) {
2050 boost::shared_ptr<Route> route = wpr.lock ();
2053 /* should not happen */
2054 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2058 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2060 shared_ptr<RouteList> r = routes.reader ();
2062 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2064 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2068 /* don't mess with busses */
2070 if (dynamic_cast<Track*>((*i).get()) == 0) {
2076 /* don't mess with tracks */
2078 if (dynamic_cast<Track*>((*i).get()) != 0) {
2083 if ((*i) != route &&
2084 ((*i)->mix_group () == 0 ||
2085 (*i)->mix_group () != route->mix_group () ||
2086 !route->mix_group ()->is_active())) {
2088 if ((*i)->soloed()) {
2090 /* if its already soloed, and solo latching is enabled,
2091 then leave it as it is.
2094 if (Config->get_solo_latched()) {
2101 solo_update_disabled = true;
2102 (*i)->set_solo (false, src);
2103 solo_update_disabled = false;
2107 bool something_soloed = false;
2108 bool same_thing_soloed = false;
2109 bool signal = false;
2111 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2112 if ((*i)->soloed()) {
2113 something_soloed = true;
2114 if (dynamic_cast<Track*>((*i).get())) {
2116 same_thing_soloed = true;
2121 same_thing_soloed = true;
2129 if (something_soloed != currently_soloing) {
2131 currently_soloing = something_soloed;
2134 modify_solo_mute (is_track, same_thing_soloed);
2137 SoloActive (currently_soloing);
2144 Session::update_route_solo_state ()
2147 bool is_track = false;
2148 bool signal = false;
2150 /* caller must hold RouteLock */
2152 /* this is where we actually implement solo by changing
2153 the solo mute setting of each track.
2156 shared_ptr<RouteList> r = routes.reader ();
2158 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2159 if ((*i)->soloed()) {
2161 if (dynamic_cast<Track*>((*i).get())) {
2168 if (mute != currently_soloing) {
2170 currently_soloing = mute;
2173 if (!is_track && !mute) {
2175 /* nothing is soloed */
2177 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2178 (*i)->set_solo_mute (false);
2188 modify_solo_mute (is_track, mute);
2191 SoloActive (currently_soloing);
2196 Session::modify_solo_mute (bool is_track, bool mute)
2198 shared_ptr<RouteList> r = routes.reader ();
2200 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2204 /* only alter track solo mute */
2206 if (dynamic_cast<Track*>((*i).get())) {
2207 if ((*i)->soloed()) {
2208 (*i)->set_solo_mute (!mute);
2210 (*i)->set_solo_mute (mute);
2216 /* only alter bus solo mute */
2218 if (!dynamic_cast<Track*>((*i).get())) {
2220 if ((*i)->soloed()) {
2222 (*i)->set_solo_mute (false);
2226 /* don't mute master or control outs
2227 in response to another bus solo
2230 if ((*i) != _master_out &&
2231 (*i) != _control_out) {
2232 (*i)->set_solo_mute (mute);
2243 Session::catch_up_on_solo ()
2245 /* this is called after set_state() to catch the full solo
2246 state, which can't be correctly determined on a per-route
2247 basis, but needs the global overview that only the session
2250 update_route_solo_state();
2254 Session::route_by_name (string name)
2256 shared_ptr<RouteList> r = routes.reader ();
2258 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2259 if ((*i)->name() == name) {
2264 return shared_ptr<Route> ((Route*) 0);
2268 Session::route_by_id (PBD::ID id)
2270 shared_ptr<RouteList> r = routes.reader ();
2272 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2273 if ((*i)->id() == id) {
2278 return shared_ptr<Route> ((Route*) 0);
2282 Session::route_by_remote_id (uint32_t id)
2284 shared_ptr<RouteList> r = routes.reader ();
2286 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2287 if ((*i)->remote_control_id() == id) {
2292 return shared_ptr<Route> ((Route*) 0);
2296 Session::find_current_end ()
2298 if (_state_of_the_state & Loading) {
2302 nframes_t max = get_maximum_extent ();
2304 if (max > end_location->end()) {
2305 end_location->set_end (max);
2307 DurationChanged(); /* EMIT SIGNAL */
2312 Session::get_maximum_extent () const
2317 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2319 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2320 Playlist* pl = (*i)->playlist();
2321 if ((me = pl->get_maximum_extent()) > max) {
2329 boost::shared_ptr<Diskstream>
2330 Session::diskstream_by_name (string name)
2332 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2334 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2335 if ((*i)->name() == name) {
2340 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2343 boost::shared_ptr<Diskstream>
2344 Session::diskstream_by_id (const PBD::ID& id)
2346 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2348 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2349 if ((*i)->id() == id) {
2354 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2357 /* Region management */
2360 Session::new_region_name (string old)
2362 string::size_type last_period;
2364 string::size_type len = old.length() + 64;
2367 if ((last_period = old.find_last_of ('.')) == string::npos) {
2369 /* no period present - add one explicitly */
2372 last_period = old.length() - 1;
2377 number = atoi (old.substr (last_period+1).c_str());
2381 while (number < (UINT_MAX-1)) {
2383 RegionList::const_iterator i;
2388 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2391 for (i = regions.begin(); i != regions.end(); ++i) {
2392 if (i->second->name() == sbuf) {
2397 if (i == regions.end()) {
2402 if (number != (UINT_MAX-1)) {
2406 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2411 Session::region_name (string& result, string base, bool newlevel) const
2416 assert(base.find("/") == string::npos);
2420 Glib::Mutex::Lock lm (region_lock);
2422 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2430 /* XXX this is going to be slow. optimize me later */
2435 string::size_type pos;
2437 pos = base.find_last_of ('.');
2439 /* pos may be npos, but then we just use entire base */
2441 subbase = base.substr (0, pos);
2445 bool name_taken = true;
2448 Glib::Mutex::Lock lm (region_lock);
2450 for (int n = 1; n < 5000; ++n) {
2453 snprintf (buf, sizeof (buf), ".%d", n);
2458 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2459 if (i->second->name() == result) {
2472 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2480 Session::add_region (boost::shared_ptr<Region> region)
2482 boost::shared_ptr<Region> other;
2486 Glib::Mutex::Lock lm (region_lock);
2488 RegionList::iterator x;
2490 for (x = regions.begin(); x != regions.end(); ++x) {
2494 if (region->region_list_equivalent (other)) {
2499 if (x == regions.end()) {
2501 pair<RegionList::key_type,RegionList::mapped_type> entry;
2503 entry.first = region->id();
2504 entry.second = region;
2506 pair<RegionList::iterator,bool> x = regions.insert (entry);
2518 /* mark dirty because something has changed even if we didn't
2519 add the region to the region list.
2525 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2526 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2527 RegionAdded (region); /* EMIT SIGNAL */
2532 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2534 boost::shared_ptr<Region> region (weak_region.lock ());
2540 if (what_changed & Region::HiddenChanged) {
2541 /* relay hidden changes */
2542 RegionHiddenChange (region);
2547 Session::remove_region (boost::weak_ptr<Region> weak_region)
2549 RegionList::iterator i;
2550 boost::shared_ptr<Region> region (weak_region.lock ());
2556 bool removed = false;
2559 Glib::Mutex::Lock lm (region_lock);
2561 if ((i = regions.find (region->id())) != regions.end()) {
2567 /* mark dirty because something has changed even if we didn't
2568 remove the region from the region list.
2574 RegionRemoved(region); /* EMIT SIGNAL */
2578 boost::shared_ptr<Region>
2579 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2581 RegionList::iterator i;
2582 boost::shared_ptr<Region> region;
2584 Glib::Mutex::Lock lm (region_lock);
2586 for (i = regions.begin(); i != regions.end(); ++i) {
2590 if (region->whole_file()) {
2592 if (child->source_equivalent (region)) {
2598 return boost::shared_ptr<Region> ();
2602 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2604 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2605 (*i)->get_region_list_equivalent_regions (region, result);
2609 Session::destroy_region (boost::shared_ptr<Region> region)
2611 vector<boost::shared_ptr<Source> > srcs;
2614 boost::shared_ptr<AudioRegion> aregion;
2616 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2620 if (aregion->playlist()) {
2621 aregion->playlist()->destroy_region (region);
2624 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2625 srcs.push_back (aregion->source (n));
2629 region->drop_references ();
2631 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2633 if (!(*i)->used()) {
2634 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2637 (afs)->mark_for_remove ();
2640 (*i)->drop_references ();
2642 cerr << "source was not used by any playlist\n";
2650 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2652 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2653 destroy_region (*i);
2659 Session::remove_last_capture ()
2661 list<boost::shared_ptr<Region> > r;
2663 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2665 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2666 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2669 r.insert (r.end(), l.begin(), l.end());
2674 destroy_regions (r);
2679 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2685 /* Source Management */
2687 Session::add_source (boost::shared_ptr<Source> source)
2689 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2690 pair<SourceMap::iterator,bool> result;
2692 entry.first = source->id();
2693 entry.second = source;
2696 Glib::Mutex::Lock lm (source_lock);
2697 result = sources.insert (entry);
2700 if (!result.second) {
2701 cerr << "\tNOT inserted ? " << result.second << endl;
2704 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2707 SourceAdded (source); /* EMIT SIGNAL */
2711 Session::remove_source (boost::weak_ptr<Source> src)
2713 SourceMap::iterator i;
2714 boost::shared_ptr<Source> source = src.lock();
2721 Glib::Mutex::Lock lm (source_lock);
2724 Glib::Mutex::Lock lm (source_lock);
2726 if ((i = sources.find (source->id())) != sources.end()) {
2732 if (!_state_of_the_state & InCleanup) {
2734 /* save state so we don't end up with a session file
2735 referring to non-existent sources.
2738 save_state (_current_snapshot_name);
2741 SourceRemoved(source); /* EMIT SIGNAL */
2744 boost::shared_ptr<Source>
2745 Session::source_by_id (const PBD::ID& id)
2747 Glib::Mutex::Lock lm (source_lock);
2748 SourceMap::iterator i;
2749 boost::shared_ptr<Source> source;
2751 if ((i = sources.find (id)) != sources.end()) {
2755 /* XXX search MIDI or other searches here */
2761 Session::peak_path_from_audio_path (string audio_path) const
2766 res += PBD::basename_nosuffix (audio_path);
2773 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2776 string old_basename = PBD::basename_nosuffix (oldname);
2777 string new_legalized = legalize_for_path (newname);
2779 /* note: we know (or assume) the old path is already valid */
2783 /* destructive file sources have a name of the form:
2785 /path/to/Tnnnn-NAME(%[LR])?.wav
2787 the task here is to replace NAME with the new name.
2790 /* find last slash */
2794 string::size_type slash;
2795 string::size_type dash;
2797 if ((slash = path.find_last_of ('/')) == string::npos) {
2801 dir = path.substr (0, slash+1);
2803 /* '-' is not a legal character for the NAME part of the path */
2805 if ((dash = path.find_last_of ('-')) == string::npos) {
2809 prefix = path.substr (slash+1, dash-(slash+1));
2814 path += new_legalized;
2815 path += ".wav"; /* XXX gag me with a spoon */
2819 /* non-destructive file sources have a name of the form:
2821 /path/to/NAME-nnnnn(%[LR])?.wav
2823 the task here is to replace NAME with the new name.
2828 string::size_type slash;
2829 string::size_type dash;
2830 string::size_type postfix;
2832 /* find last slash */
2834 if ((slash = path.find_last_of ('/')) == string::npos) {
2838 dir = path.substr (0, slash+1);
2840 /* '-' is not a legal character for the NAME part of the path */
2842 if ((dash = path.find_last_of ('-')) == string::npos) {
2846 suffix = path.substr (dash+1);
2848 // Suffix is now everything after the dash. Now we need to eliminate
2849 // the nnnnn part, which is done by either finding a '%' or a '.'
2851 postfix = suffix.find_last_of ("%");
2852 if (postfix == string::npos) {
2853 postfix = suffix.find_last_of ('.');
2856 if (postfix != string::npos) {
2857 suffix = suffix.substr (postfix);
2859 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2863 const uint32_t limit = 10000;
2864 char buf[PATH_MAX+1];
2866 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2868 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2870 if (access (buf, F_OK) != 0) {
2878 error << "FATAL ERROR! Could not find a " << endl;
2887 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2891 char buf[PATH_MAX+1];
2892 const uint32_t limit = 10000;
2896 legalized = legalize_for_path (name);
2898 /* find a "version" of the file name that doesn't exist in
2899 any of the possible directories.
2902 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2904 vector<space_and_path>::iterator i;
2905 uint32_t existing = 0;
2907 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2911 spath += sound_dir (false);
2915 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2916 } else if (nchan == 2) {
2918 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2920 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2922 } else if (nchan < 26) {
2923 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2925 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2933 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2934 } else if (nchan == 2) {
2936 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2938 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2940 } else if (nchan < 26) {
2941 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2943 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2947 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2953 if (existing == 0) {
2958 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2959 throw failed_constructor();
2963 /* we now have a unique name for the file, but figure out where to
2969 spath = discover_best_sound_dir ();
2971 string::size_type pos = foo.find_last_of ('/');
2973 if (pos == string::npos) {
2976 spath += foo.substr (pos + 1);
2982 boost::shared_ptr<AudioFileSource>
2983 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2985 string spath = audio_path_from_name (ds.name(), ds.n_channels().get(DataType::AUDIO), chan, destructive);
2986 return boost::dynamic_pointer_cast<AudioFileSource> (
2987 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
2990 // FIXME: _terrible_ code duplication
2992 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
2995 string old_basename = PBD::basename_nosuffix (oldname);
2996 string new_legalized = legalize_for_path (newname);
2998 /* note: we know (or assume) the old path is already valid */
3002 /* destructive file sources have a name of the form:
3004 /path/to/Tnnnn-NAME(%[LR])?.wav
3006 the task here is to replace NAME with the new name.
3009 /* find last slash */
3013 string::size_type slash;
3014 string::size_type dash;
3016 if ((slash = path.find_last_of ('/')) == string::npos) {
3020 dir = path.substr (0, slash+1);
3022 /* '-' is not a legal character for the NAME part of the path */
3024 if ((dash = path.find_last_of ('-')) == string::npos) {
3028 prefix = path.substr (slash+1, dash-(slash+1));
3033 path += new_legalized;
3034 path += ".mid"; /* XXX gag me with a spoon */
3038 /* non-destructive file sources have a name of the form:
3040 /path/to/NAME-nnnnn(%[LR])?.wav
3042 the task here is to replace NAME with the new name.
3047 string::size_type slash;
3048 string::size_type dash;
3049 string::size_type postfix;
3051 /* find last slash */
3053 if ((slash = path.find_last_of ('/')) == string::npos) {
3057 dir = path.substr (0, slash+1);
3059 /* '-' is not a legal character for the NAME part of the path */
3061 if ((dash = path.find_last_of ('-')) == string::npos) {
3065 suffix = path.substr (dash+1);
3067 // Suffix is now everything after the dash. Now we need to eliminate
3068 // the nnnnn part, which is done by either finding a '%' or a '.'
3070 postfix = suffix.find_last_of ("%");
3071 if (postfix == string::npos) {
3072 postfix = suffix.find_last_of ('.');
3075 if (postfix != string::npos) {
3076 suffix = suffix.substr (postfix);
3078 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3082 const uint32_t limit = 10000;
3083 char buf[PATH_MAX+1];
3085 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3087 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3089 if (access (buf, F_OK) != 0) {
3097 error << "FATAL ERROR! Could not find a " << endl;
3106 Session::midi_path_from_name (string name)
3110 char buf[PATH_MAX+1];
3111 const uint32_t limit = 10000;
3115 legalized = legalize_for_path (name);
3117 /* find a "version" of the file name that doesn't exist in
3118 any of the possible directories.
3121 for (cnt = 1; cnt <= limit; ++cnt) {
3123 vector<space_and_path>::iterator i;
3124 uint32_t existing = 0;
3126 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3128 // FIXME: different directory from audio?
3129 spath = (*i).path + sound_dir_name + "/" + legalized;
3131 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3133 if (access (buf, F_OK) == 0) {
3138 if (existing == 0) {
3143 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3144 throw failed_constructor();
3148 /* we now have a unique name for the file, but figure out where to
3154 // FIXME: different directory than audio?
3155 spath = discover_best_sound_dir ();
3157 string::size_type pos = foo.find_last_of ('/');
3159 if (pos == string::npos) {
3162 spath += foo.substr (pos + 1);
3168 boost::shared_ptr<MidiSource>
3169 Session::create_midi_source_for_session (MidiDiskstream& ds)
3171 string spath = midi_path_from_name (ds.name());
3173 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
3177 /* Playlist management */
3180 Session::playlist_by_name (string name)
3182 Glib::Mutex::Lock lm (playlist_lock);
3183 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3184 if ((*i)->name() == name) {
3188 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3189 if ((*i)->name() == name) {
3197 Session::add_playlist (Playlist* playlist)
3199 if (playlist->hidden()) {
3204 Glib::Mutex::Lock lm (playlist_lock);
3205 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3206 playlists.insert (playlists.begin(), playlist);
3208 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3209 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
3215 PlaylistAdded (playlist); /* EMIT SIGNAL */
3219 Session::get_playlists (vector<Playlist*>& s)
3222 Glib::Mutex::Lock lm (playlist_lock);
3223 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3226 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3233 Session::track_playlist (Playlist* pl, bool inuse)
3235 PlaylistList::iterator x;
3238 Glib::Mutex::Lock lm (playlist_lock);
3241 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3243 unused_playlists.insert (pl);
3245 if ((x = playlists.find (pl)) != playlists.end()) {
3246 playlists.erase (x);
3251 //cerr << "shifting playlist to used: " << pl->name() << endl;
3253 playlists.insert (pl);
3255 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3256 unused_playlists.erase (x);
3263 Session::remove_playlist (Playlist* playlist)
3265 if (_state_of_the_state & Deletion) {
3270 Glib::Mutex::Lock lm (playlist_lock);
3271 // cerr << "removing playlist: " << playlist->name() << endl;
3273 PlaylistList::iterator i;
3275 i = find (playlists.begin(), playlists.end(), playlist);
3277 if (i != playlists.end()) {
3278 playlists.erase (i);
3281 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3282 if (i != unused_playlists.end()) {
3283 unused_playlists.erase (i);
3290 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3294 Session::set_audition (boost::shared_ptr<Region> r)
3296 pending_audition_region = r;
3297 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3298 schedule_butler_transport_work ();
3302 Session::audition_playlist ()
3304 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3305 ev->region.reset ();
3310 Session::non_realtime_set_audition ()
3312 if (!pending_audition_region) {
3313 auditioner->audition_current_playlist ();
3315 auditioner->audition_region (pending_audition_region);
3316 pending_audition_region.reset ();
3318 AuditionActive (true); /* EMIT SIGNAL */
3322 Session::audition_region (boost::shared_ptr<Region> r)
3324 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3330 Session::cancel_audition ()
3332 if (auditioner->active()) {
3333 auditioner->cancel_audition ();
3334 AuditionActive (false); /* EMIT SIGNAL */
3339 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3341 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3345 Session::remove_empty_sounds ()
3347 PathScanner scanner;
3349 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3351 Glib::Mutex::Lock lm (source_lock);
3353 regex_t compiled_tape_track_pattern;
3356 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3360 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3362 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3366 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3368 /* never remove files that appear to be a tape track */
3370 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3375 if (AudioFileSource::is_empty (*this, *(*i))) {
3377 unlink ((*i)->c_str());
3379 string peak_path = peak_path_from_audio_path (**i);
3380 unlink (peak_path.c_str());
3386 delete possible_audiofiles;
3390 Session::is_auditioning () const
3392 /* can be called before we have an auditioner object */
3394 return auditioner->active();
3401 Session::set_all_solo (bool yn)
3403 shared_ptr<RouteList> r = routes.reader ();
3405 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3406 if (!(*i)->hidden()) {
3407 (*i)->set_solo (yn, this);
3415 Session::set_all_mute (bool yn)
3417 shared_ptr<RouteList> r = routes.reader ();
3419 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3420 if (!(*i)->hidden()) {
3421 (*i)->set_mute (yn, this);
3429 Session::n_diskstreams () const
3433 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3435 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3436 if (!(*i)->hidden()) {
3444 Session::graph_reordered ()
3446 /* don't do this stuff if we are setting up connections
3447 from a set_state() call.
3450 if (_state_of_the_state & InitialConnecting) {
3456 /* force all diskstreams to update their capture offset values to
3457 reflect any changes in latencies within the graph.
3460 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3462 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3463 (*i)->set_capture_offset ();
3468 Session::record_disenable_all ()
3470 record_enable_change_all (false);
3474 Session::record_enable_all ()
3476 record_enable_change_all (true);
3480 Session::record_enable_change_all (bool yn)
3482 shared_ptr<RouteList> r = routes.reader ();
3484 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3487 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3488 at->set_record_enable (yn, this);
3492 /* since we don't keep rec-enable state, don't mark session dirty */
3496 Session::add_redirect (Redirect* redirect)
3500 PortInsert* port_insert;
3501 PluginInsert* plugin_insert;
3503 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3504 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3505 _port_inserts.insert (_port_inserts.begin(), port_insert);
3506 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3507 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3509 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3512 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3513 _sends.insert (_sends.begin(), send);
3515 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3519 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3525 Session::remove_redirect (Redirect* redirect)
3529 PortInsert* port_insert;
3530 PluginInsert* plugin_insert;
3532 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3533 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3534 _port_inserts.remove (port_insert);
3535 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3536 _plugin_inserts.remove (plugin_insert);
3538 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3541 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3542 _sends.remove (send);
3544 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3552 Session::available_capture_duration ()
3554 float sample_bytes_on_disk;
3556 switch (Config->get_native_file_data_format()) {
3558 sample_bytes_on_disk = 4;
3562 sample_bytes_on_disk = 3;
3566 double scale = 4096.0 / sample_bytes_on_disk;
3568 if (_total_free_4k_blocks * scale > (double) max_frames) {
3572 return (nframes_t) floor (_total_free_4k_blocks * scale);
3576 Session::add_connection (ARDOUR::Connection* connection)
3579 Glib::Mutex::Lock guard (connection_lock);
3580 _connections.push_back (connection);
3583 ConnectionAdded (connection); /* EMIT SIGNAL */
3589 Session::remove_connection (ARDOUR::Connection* connection)
3591 bool removed = false;
3594 Glib::Mutex::Lock guard (connection_lock);
3595 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3597 if (i != _connections.end()) {
3598 _connections.erase (i);
3604 ConnectionRemoved (connection); /* EMIT SIGNAL */
3610 ARDOUR::Connection *
3611 Session::connection_by_name (string name) const
3613 Glib::Mutex::Lock lm (connection_lock);
3615 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3616 if ((*i)->name() == name) {
3625 Session::tempo_map_changed (Change ignored)
3631 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3632 * the given count with the current block size.
3635 Session::ensure_buffers (ChanCount howmany)
3637 // FIXME: NASTY assumption (midi block size == audio block size)
3638 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3639 _send_buffers->ensure_buffers(howmany, current_block_size);
3640 _silent_buffers->ensure_buffers(howmany, current_block_size);
3642 allocate_pan_automation_buffers (current_block_size, howmany.get(DataType::AUDIO), false);
3646 Session::next_send_name ()
3649 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3654 Session::next_insert_name ()
3657 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3661 /* Named Selection management */
3664 Session::named_selection_by_name (string name)
3666 Glib::Mutex::Lock lm (named_selection_lock);
3667 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3668 if ((*i)->name == name) {
3676 Session::add_named_selection (NamedSelection* named_selection)
3679 Glib::Mutex::Lock lm (named_selection_lock);
3680 named_selections.insert (named_selections.begin(), named_selection);
3685 NamedSelectionAdded (); /* EMIT SIGNAL */
3689 Session::remove_named_selection (NamedSelection* named_selection)
3691 bool removed = false;
3694 Glib::Mutex::Lock lm (named_selection_lock);
3696 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3698 if (i != named_selections.end()) {
3700 named_selections.erase (i);
3707 NamedSelectionRemoved (); /* EMIT SIGNAL */
3712 Session::reset_native_file_format ()
3714 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3716 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3717 (*i)->reset_write_sources (false);
3722 Session::route_name_unique (string n) const
3724 shared_ptr<RouteList> r = routes.reader ();
3726 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3727 if ((*i)->name() == n) {
3736 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3738 return fs->move_to_trash (dead_sound_dir_name);
3742 Session::n_playlists () const
3744 Glib::Mutex::Lock lm (playlist_lock);
3745 return playlists.size();
3749 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3751 if (!force && howmany <= _npan_buffers) {
3755 if (_pan_automation_buffer) {
3757 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3758 delete [] _pan_automation_buffer[i];
3761 delete [] _pan_automation_buffer;
3764 _pan_automation_buffer = new pan_t*[howmany];
3766 for (uint32_t i = 0; i < howmany; ++i) {
3767 _pan_automation_buffer[i] = new pan_t[nframes];
3770 _npan_buffers = howmany;
3774 Session::freeze (InterThreadInfo& itt)
3776 shared_ptr<RouteList> r = routes.reader ();
3778 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3782 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3783 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3794 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3795 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3797 boost::shared_ptr<AudioFileSource> fsource;
3800 Playlist* playlist = 0;
3802 char buf[PATH_MAX+1];
3804 ChanCount nchans(track.audio_diskstream()->n_channels());
3805 jack_nframes_t position;
3806 jack_nframes_t this_chunk;
3807 jack_nframes_t to_do;
3810 // any bigger than this seems to cause stack overflows in called functions
3811 const nframes_t chunk_size = (128 * 1024)/4;
3813 g_atomic_int_set (&processing_prohibited, 1);
3815 /* call tree *MUST* hold route_lock */
3817 if ((playlist = track.diskstream()->playlist()) == 0) {
3821 /* external redirects will be a problem */
3823 if (track.has_external_redirects()) {
3827 dir = discover_best_sound_dir ();
3829 for (uint32_t chan_n=0; chan_n < nchans.get(DataType::AUDIO); ++chan_n) {
3831 for (x = 0; x < 99999; ++x) {
3832 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3833 if (access (buf, F_OK) != 0) {
3839 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3844 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3845 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3848 catch (failed_constructor& err) {
3849 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3853 srcs.push_back (fsource);
3856 /* XXX need to flush all redirects */
3861 /* create a set of reasonably-sized buffers */
3862 buffers.ensure_buffers(nchans, chunk_size);
3863 buffers.set_count(nchans);
3865 while (to_do && !itt.cancel) {
3867 this_chunk = min (to_do, chunk_size);
3869 if (track.export_stuff (buffers, start, this_chunk)) {
3874 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3875 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3878 if (afs->write (buffers.get_audio(n).data(this_chunk), this_chunk) != this_chunk) {
3884 start += this_chunk;
3885 to_do -= this_chunk;
3887 itt.progress = (float) (1.0 - ((double) to_do / len));
3896 xnow = localtime (&now);
3898 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3899 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3902 afs->update_header (position, *xnow, now);
3906 /* build peakfile for new source */
3908 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3909 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3911 afs->build_peaks ();
3915 /* construct a region to represent the bounced material */
3917 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3918 region_name_from_path (srcs.front()->name()));
3925 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3926 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3929 afs->mark_for_remove ();
3932 (*src)->drop_references ();
3936 g_atomic_int_set (&processing_prohibited, 0);
3944 Session::get_silent_buffers (ChanCount count)
3946 assert(_silent_buffers->available() >= count);
3947 _silent_buffers->set_count(count);
3949 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3950 for (size_t i=0; i < count.get(*t); ++i) {
3951 _silent_buffers->get(*t, i).clear();
3955 return *_silent_buffers;
3959 Session::get_scratch_buffers (ChanCount count)
3961 assert(_scratch_buffers->available() >= count);
3962 _scratch_buffers->set_count(count);
3963 return *_scratch_buffers;
3967 Session::get_send_buffers (ChanCount count)
3969 assert(_send_buffers->available() >= count);
3970 _send_buffers->set_count(count);
3971 return *_send_buffers;
3975 Session::ntracks () const
3978 shared_ptr<RouteList> r = routes.reader ();
3980 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3981 if (dynamic_cast<Track*> ((*i).get())) {
3990 Session::nbusses () const
3993 shared_ptr<RouteList> r = routes.reader ();
3995 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3996 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4005 Session::add_automation_list(AutomationList *al)
4007 automation_lists[al->id()] = al;
4011 Session::compute_initial_length ()
4013 return _engine.frame_rate() * 60 * 5;