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, _engine.frame_rate() * 60 * 5)) {
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 = max (requested_physical_out, _engine.n_physical_outputs());
346 n_physical_inputs = max (requested_physical_in, _engine.n_physical_inputs());
348 first_stage_init (fullpath, snapshot_name);
350 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
352 if (create (new_session, 0, initial_length)) {
353 throw failed_constructor ();
357 if (control_out_channels) {
358 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
365 if (master_out_channels) {
366 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
372 /* prohibit auto-connect to master, because there isn't one */
373 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
376 Config->set_input_auto_connect (input_ac);
377 Config->set_output_auto_connect (output_ac);
379 if (second_stage_init (new_session)) {
380 throw failed_constructor ();
383 store_recent_sessions(_name, _path);
385 bool was_dirty = dirty ();
387 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
390 DirtyChanged (); /* EMIT SIGNAL */
396 /* if we got to here, leaving pending capture state around
400 remove_pending_capture_state ();
402 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
403 _engine.remove_session ();
405 GoingAway (); /* EMIT SIGNAL */
411 /* clear history so that no references to objects are held any more */
415 /* clear state tree so that no references to objects are held any more */
421 terminate_butler_thread ();
422 //terminate_midi_thread ();
424 if (click_data && click_data != default_click) {
425 delete [] click_data;
428 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
429 delete [] click_emphasis_data;
434 delete _scratch_buffers;
435 delete _silent_buffers;
436 delete _send_buffers;
438 AudioDiskstream::free_working_buffers();
440 #undef TRACK_DESTRUCTION
441 #ifdef TRACK_DESTRUCTION
442 cerr << "delete named selections\n";
443 #endif /* TRACK_DESTRUCTION */
444 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
445 NamedSelectionList::iterator tmp;
454 #ifdef TRACK_DESTRUCTION
455 cerr << "delete playlists\n";
456 #endif /* TRACK_DESTRUCTION */
457 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
458 PlaylistList::iterator tmp;
468 #ifdef TRACK_DESTRUCTION
469 cerr << "delete regions\n";
470 #endif /* TRACK_DESTRUCTION */
472 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
473 RegionList::iterator tmp;
478 cerr << "dropping refs on a region (" << i->second->name() << " @ " << i->second << ") with UC = " << i->second.use_count() << endl;
479 i->second->drop_references ();
480 cerr << "AFTER: UC = " << i->second.use_count() << endl;
487 #ifdef TRACK_DESTRUCTION
488 cerr << "delete routes\n";
489 #endif /* TRACK_DESTRUCTION */
491 RCUWriter<RouteList> writer (routes);
492 boost::shared_ptr<RouteList> r = writer.get_copy ();
493 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
494 (*i)->drop_references ();
497 /* writer goes out of scope and updates master */
502 #ifdef TRACK_DESTRUCTION
503 cerr << "delete diskstreams\n";
504 #endif /* TRACK_DESTRUCTION */
506 RCUWriter<DiskstreamList> dwriter (diskstreams);
507 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
508 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
509 (*i)->drop_references ();
513 diskstreams.flush ();
515 #ifdef TRACK_DESTRUCTION
516 cerr << "delete audio sources\n";
517 #endif /* TRACK_DESTRUCTION */
518 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
519 SourceMap::iterator tmp;
524 i->second->drop_references ();
531 #ifdef TRACK_DESTRUCTION
532 cerr << "delete mix groups\n";
533 #endif /* TRACK_DESTRUCTION */
534 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
535 list<RouteGroup*>::iterator tmp;
545 #ifdef TRACK_DESTRUCTION
546 cerr << "delete edit groups\n";
547 #endif /* TRACK_DESTRUCTION */
548 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
549 list<RouteGroup*>::iterator tmp;
559 #ifdef TRACK_DESTRUCTION
560 cerr << "delete connections\n";
561 #endif /* TRACK_DESTRUCTION */
562 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
563 ConnectionList::iterator tmp;
573 if (butler_mixdown_buffer) {
574 delete [] butler_mixdown_buffer;
577 if (butler_gain_buffer) {
578 delete [] butler_gain_buffer;
581 Crossfade::set_buffer_size (0);
589 Session::set_worst_io_latencies ()
591 _worst_output_latency = 0;
592 _worst_input_latency = 0;
594 if (!_engine.connected()) {
598 boost::shared_ptr<RouteList> r = routes.reader ();
600 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
601 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
602 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
607 Session::when_engine_running ()
609 string first_physical_output;
611 /* we don't want to run execute this again */
613 first_time_running.disconnect ();
615 set_block_size (_engine.frames_per_cycle());
616 set_frame_rate (_engine.frame_rate());
618 Config->map_parameters (mem_fun (*this, &Session::config_changed));
620 /* every time we reconnect, recompute worst case output latencies */
622 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
624 if (synced_to_jack()) {
625 _engine.transport_stop ();
628 if (Config->get_jack_time_master()) {
629 _engine.transport_locate (_transport_frame);
637 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
639 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
641 /* existing state for Click */
643 if (_click_io->set_state (*child->children().front()) == 0) {
645 _clicking = Config->get_clicking ();
649 error << _("could not setup Click I/O") << endmsg;
655 /* default state for Click */
657 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
659 if (first_physical_output.length()) {
660 if (_click_io->add_output_port (first_physical_output, this)) {
661 // relax, even though its an error
663 _clicking = Config->get_clicking ();
669 catch (failed_constructor& err) {
670 error << _("cannot setup Click I/O") << endmsg;
673 set_worst_io_latencies ();
676 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
679 if (auditioner == 0) {
681 /* we delay creating the auditioner till now because
682 it makes its own connections to ports named
683 in the ARDOUR_RC config file. the engine has
684 to be running for this to work.
688 auditioner.reset (new Auditioner (*this));
691 catch (failed_constructor& err) {
692 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
696 /* Create a set of Connection objects that map
697 to the physical outputs currently available
702 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
704 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
706 Connection* c = new OutputConnection (buf, true);
709 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
714 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
716 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
718 Connection* c = new InputConnection (buf, true);
721 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
728 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
730 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
732 Connection* c = new OutputConnection (buf, true);
736 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
737 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
742 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
744 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
746 Connection* c = new InputConnection (buf, true);
750 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
751 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
760 /* create master/control ports */
765 /* force the master to ignore any later call to this */
767 if (_master_out->pending_state_node) {
768 _master_out->ports_became_legal();
771 /* no panner resets till we are through */
773 _master_out->defer_pan_reset ();
775 while (_master_out->n_inputs().get(DataType::AUDIO)
776 < _master_out->input_maximum().get(DataType::AUDIO)) {
777 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
778 error << _("cannot setup master inputs")
784 while (_master_out->n_outputs().get(DataType::AUDIO)
785 < _master_out->output_maximum().get(DataType::AUDIO)) {
786 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
787 error << _("cannot setup master outputs")
794 _master_out->allow_pan_reset ();
798 Connection* c = new OutputConnection (_("Master Out"), true);
800 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
802 c->add_connection ((int) n, _master_out->input(n)->name());
809 /* catch up on send+insert cnts */
813 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
816 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
817 if (id > insert_cnt) {
825 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
828 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
835 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
837 /* hook us up to the engine */
839 _engine.set_session (this);
844 osc->set_session (*this);
847 _state_of_the_state = Clean;
849 DirtyChanged (); /* EMIT SIGNAL */
853 Session::hookup_io ()
855 /* stop graph reordering notifications from
856 causing resorts, etc.
859 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
861 /* Tell all IO objects to create their ports */
868 while (_control_out->n_inputs().get(DataType::AUDIO) < _control_out->input_maximum().get(DataType::AUDIO)) {
869 if (_control_out->add_input_port ("", this)) {
870 error << _("cannot setup control inputs")
876 while (_control_out->n_outputs().get(DataType::AUDIO) < _control_out->output_maximum().get(DataType::AUDIO)) {
877 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
878 error << _("cannot set up master outputs")
886 /* Tell all IO objects to connect themselves together */
888 IO::enable_connecting ();
890 /* Now reset all panners */
892 IO::reset_panners ();
894 /* Anyone who cares about input state, wake up and do something */
896 IOConnectionsComplete (); /* EMIT SIGNAL */
898 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
900 /* now handle the whole enchilada as if it was one
906 /* update mixer solo state */
912 Session::playlist_length_changed (Playlist* pl)
914 /* we can't just increase end_location->end() if pl->get_maximum_extent()
915 if larger. if the playlist used to be the longest playlist,
916 and its now shorter, we have to decrease end_location->end(). hence,
917 we have to iterate over all diskstreams and check the
918 playlists currently in use.
924 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
928 if ((playlist = dstream->playlist()) != 0) {
929 playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
932 /* see comment in playlist_length_changed () */
937 Session::record_enabling_legal () const
939 /* this used to be in here, but survey says.... we don't need to restrict it */
940 // if (record_status() == Recording) {
944 if (Config->get_all_safe()) {
951 Session::reset_input_monitor_state ()
953 if (transport_rolling()) {
955 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
957 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
958 if ((*i)->record_enabled ()) {
959 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
960 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
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 = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
969 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
976 Session::auto_punch_start_changed (Location* location)
978 replace_event (Event::PunchIn, location->start());
980 if (get_record_enabled() && Config->get_punch_in()) {
981 /* capture start has been changed, so save new pending state */
982 save_state ("", true);
987 Session::auto_punch_end_changed (Location* location)
989 nframes_t when_to_stop = location->end();
990 // when_to_stop += _worst_output_latency + _worst_input_latency;
991 replace_event (Event::PunchOut, when_to_stop);
995 Session::auto_punch_changed (Location* location)
997 nframes_t when_to_stop = location->end();
999 replace_event (Event::PunchIn, location->start());
1000 //when_to_stop += _worst_output_latency + _worst_input_latency;
1001 replace_event (Event::PunchOut, when_to_stop);
1005 Session::auto_loop_changed (Location* location)
1007 replace_event (Event::AutoLoop, location->end(), location->start());
1009 if (transport_rolling() && play_loop) {
1011 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1013 if (_transport_frame > location->end()) {
1014 // relocate to beginning of loop
1015 clear_events (Event::LocateRoll);
1017 request_locate (location->start(), true);
1020 else if (Config->get_seamless_loop() && !loop_changing) {
1022 // schedule a locate-roll to refill the diskstreams at the
1023 // previous loop end
1024 loop_changing = true;
1026 if (location->end() > last_loopend) {
1027 clear_events (Event::LocateRoll);
1028 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1035 last_loopend = location->end();
1040 Session::set_auto_punch_location (Location* location)
1044 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1045 auto_punch_start_changed_connection.disconnect();
1046 auto_punch_end_changed_connection.disconnect();
1047 auto_punch_changed_connection.disconnect();
1048 existing->set_auto_punch (false, this);
1049 remove_event (existing->start(), Event::PunchIn);
1050 clear_events (Event::PunchOut);
1051 auto_punch_location_changed (0);
1056 if (location == 0) {
1060 if (location->end() <= location->start()) {
1061 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1065 auto_punch_start_changed_connection.disconnect();
1066 auto_punch_end_changed_connection.disconnect();
1067 auto_punch_changed_connection.disconnect();
1069 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1070 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1071 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1073 location->set_auto_punch (true, this);
1074 auto_punch_location_changed (location);
1078 Session::set_auto_loop_location (Location* location)
1082 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1083 auto_loop_start_changed_connection.disconnect();
1084 auto_loop_end_changed_connection.disconnect();
1085 auto_loop_changed_connection.disconnect();
1086 existing->set_auto_loop (false, this);
1087 remove_event (existing->end(), Event::AutoLoop);
1088 auto_loop_location_changed (0);
1093 if (location == 0) {
1097 if (location->end() <= location->start()) {
1098 error << _("Session: you can't use a mark for auto loop") << endmsg;
1102 last_loopend = location->end();
1104 auto_loop_start_changed_connection.disconnect();
1105 auto_loop_end_changed_connection.disconnect();
1106 auto_loop_changed_connection.disconnect();
1108 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1109 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1110 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1112 location->set_auto_loop (true, this);
1113 auto_loop_location_changed (location);
1117 Session::locations_added (Location* ignored)
1123 Session::locations_changed ()
1125 _locations.apply (*this, &Session::handle_locations_changed);
1129 Session::handle_locations_changed (Locations::LocationList& locations)
1131 Locations::LocationList::iterator i;
1133 bool set_loop = false;
1134 bool set_punch = false;
1136 for (i = locations.begin(); i != locations.end(); ++i) {
1140 if (location->is_auto_punch()) {
1141 set_auto_punch_location (location);
1144 if (location->is_auto_loop()) {
1145 set_auto_loop_location (location);
1152 set_auto_loop_location (0);
1155 set_auto_punch_location (0);
1162 Session::enable_record ()
1164 /* XXX really atomic compare+swap here */
1165 if (g_atomic_int_get (&_record_status) != Recording) {
1166 g_atomic_int_set (&_record_status, Recording);
1167 _last_record_location = _transport_frame;
1168 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1170 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1171 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1172 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1173 if ((*i)->record_enabled ()) {
1174 (*i)->monitor_input (true);
1179 RecordStateChanged ();
1184 Session::disable_record (bool rt_context, bool force)
1188 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1190 if (!Config->get_latched_record_enable () || force) {
1191 g_atomic_int_set (&_record_status, Disabled);
1193 if (rs == Recording) {
1194 g_atomic_int_set (&_record_status, Enabled);
1198 // FIXME: timestamp correct? [DR]
1199 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1200 // does this /need/ to be sent in all cases?
1202 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1204 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1205 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1207 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1208 if ((*i)->record_enabled ()) {
1209 (*i)->monitor_input (false);
1214 RecordStateChanged (); /* emit signal */
1217 remove_pending_capture_state ();
1223 Session::step_back_from_record ()
1225 g_atomic_int_set (&_record_status, Enabled);
1227 if (Config->get_monitoring_model() == HardwareMonitoring) {
1228 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1230 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1231 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1232 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1233 (*i)->monitor_input (false);
1240 Session::maybe_enable_record ()
1242 g_atomic_int_set (&_record_status, Enabled);
1244 /* this function is currently called from somewhere other than an RT thread.
1245 this save_state() call therefore doesn't impact anything.
1248 save_state ("", true);
1250 if (_transport_speed) {
1251 if (!Config->get_punch_in()) {
1255 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1256 RecordStateChanged (); /* EMIT SIGNAL */
1263 Session::audible_frame () const
1269 /* the first of these two possible settings for "offset"
1270 mean that the audible frame is stationary until
1271 audio emerges from the latency compensation
1274 the second means that the audible frame is stationary
1275 until audio would emerge from a physical port
1276 in the absence of any plugin latency compensation
1279 offset = _worst_output_latency;
1281 if (offset > current_block_size) {
1282 offset -= current_block_size;
1284 /* XXX is this correct? if we have no external
1285 physical connections and everything is internal
1286 then surely this is zero? still, how
1287 likely is that anyway?
1289 offset = current_block_size;
1292 if (synced_to_jack()) {
1293 tf = _engine.transport_frame();
1295 tf = _transport_frame;
1298 if (_transport_speed == 0) {
1308 if (!non_realtime_work_pending()) {
1312 /* take latency into account */
1321 Session::set_frame_rate (nframes_t frames_per_second)
1323 /** \fn void Session::set_frame_size(nframes_t)
1324 the AudioEngine object that calls this guarantees
1325 that it will not be called while we are also in
1326 ::process(). Its fine to do things that block
1330 _base_frame_rate = frames_per_second;
1334 // XXX we need some equivalent to this, somehow
1335 // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
1339 /* XXX need to reset/reinstantiate all LADSPA plugins */
1343 Session::set_block_size (nframes_t nframes)
1345 /* the AudioEngine guarantees
1346 that it will not be called while we are also in
1347 ::process(). It is therefore fine to do things that block
1353 current_block_size = nframes;
1355 ensure_buffers(_scratch_buffers->available());
1357 if (_gain_automation_buffer) {
1358 delete [] _gain_automation_buffer;
1360 _gain_automation_buffer = new gain_t[nframes];
1362 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1364 boost::shared_ptr<RouteList> r = routes.reader ();
1366 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1367 (*i)->set_block_size (nframes);
1370 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1371 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1372 (*i)->set_block_size (nframes);
1375 set_worst_io_latencies ();
1380 Session::set_default_fade (float steepness, float fade_msecs)
1383 nframes_t fade_frames;
1385 /* Don't allow fade of less 1 frame */
1387 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1394 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1398 default_fade_msecs = fade_msecs;
1399 default_fade_steepness = steepness;
1402 // jlc, WTF is this!
1403 Glib::RWLock::ReaderLock lm (route_lock);
1404 AudioRegion::set_default_fade (steepness, fade_frames);
1409 /* XXX have to do this at some point */
1410 /* foreach region using default fade, reset, then
1411 refill_all_diskstream_buffers ();
1416 struct RouteSorter {
1417 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1418 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1420 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1423 if (r1->fed_by.empty()) {
1424 if (r2->fed_by.empty()) {
1425 /* no ardour-based connections inbound to either route. just use signal order */
1426 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1428 /* r2 has connections, r1 does not; run r1 early */
1432 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1439 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1441 shared_ptr<Route> r2;
1443 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1444 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1448 /* make a copy of the existing list of routes that feed r1 */
1450 set<shared_ptr<Route> > existing = r1->fed_by;
1452 /* for each route that feeds r1, recurse, marking it as feeding
1456 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1459 /* r2 is a route that feeds r1 which somehow feeds base. mark
1460 base as being fed by r2
1463 rbase->fed_by.insert (r2);
1467 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1471 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1475 /* now recurse, so that we can mark base as being fed by
1476 all routes that feed r2
1479 trace_terminal (r2, rbase);
1486 Session::resort_routes ()
1488 /* don't do anything here with signals emitted
1489 by Routes while we are being destroyed.
1492 if (_state_of_the_state & Deletion) {
1499 RCUWriter<RouteList> writer (routes);
1500 shared_ptr<RouteList> r = writer.get_copy ();
1501 resort_routes_using (r);
1502 /* writer goes out of scope and forces update */
1507 Session::resort_routes_using (shared_ptr<RouteList> r)
1509 RouteList::iterator i, j;
1511 for (i = r->begin(); i != r->end(); ++i) {
1513 (*i)->fed_by.clear ();
1515 for (j = r->begin(); j != r->end(); ++j) {
1517 /* although routes can feed themselves, it will
1518 cause an endless recursive descent if we
1519 detect it. so don't bother checking for
1527 if ((*j)->feeds (*i)) {
1528 (*i)->fed_by.insert (*j);
1533 for (i = r->begin(); i != r->end(); ++i) {
1534 trace_terminal (*i, *i);
1541 cerr << "finished route resort\n";
1543 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1544 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1551 list<boost::shared_ptr<MidiTrack> >
1552 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1554 char track_name[32];
1555 uint32_t track_id = 0;
1557 uint32_t channels_used = 0;
1559 RouteList new_routes;
1560 list<boost::shared_ptr<MidiTrack> > ret;
1562 /* count existing midi tracks */
1565 shared_ptr<RouteList> r = routes.reader ();
1567 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1568 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1569 if (!(*i)->hidden()) {
1571 channels_used += (*i)->n_inputs().get(DataType::MIDI);
1579 /* check for duplicate route names, since we might have pre-existing
1580 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1581 save, close,restart,add new route - first named route is now
1589 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1591 if (route_by_name (track_name) == 0) {
1595 } while (track_id < (UINT_MAX-1));
1598 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1600 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1601 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1604 channels_used += track->n_inputs ().get(DataType::MIDI);
1606 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1607 track->set_remote_control_id (ntracks());
1609 new_routes.push_back (track);
1610 ret.push_back (track);
1613 catch (failed_constructor &err) {
1614 error << _("Session: could not create new midi track.") << endmsg;
1615 // XXX should we delete the tracks already created?
1623 if (!new_routes.empty()) {
1624 add_routes (new_routes, false);
1625 save_state (_current_snapshot_name);
1631 list<boost::shared_ptr<AudioTrack> >
1632 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1634 char track_name[32];
1635 uint32_t track_id = 0;
1637 uint32_t channels_used = 0;
1639 RouteList new_routes;
1640 list<boost::shared_ptr<AudioTrack> > ret;
1642 /* count existing audio tracks */
1645 shared_ptr<RouteList> r = routes.reader ();
1647 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1648 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1649 if (!(*i)->hidden()) {
1651 channels_used += (*i)->n_inputs().get(DataType::AUDIO);
1657 vector<string> physinputs;
1658 vector<string> physoutputs;
1659 uint32_t nphysical_in;
1660 uint32_t nphysical_out;
1662 _engine.get_physical_outputs (physoutputs);
1663 _engine.get_physical_inputs (physinputs);
1667 /* check for duplicate route names, since we might have pre-existing
1668 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1669 save, close,restart,add new route - first named route is now
1677 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1679 if (route_by_name (track_name) == 0) {
1683 } while (track_id < (UINT_MAX-1));
1685 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1686 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1691 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1692 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1698 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1700 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1701 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1702 input_channels, output_channels)
1707 for (uint32_t x = 0; x < track->n_inputs().get(DataType::AUDIO) && x < nphysical_in; ++x) {
1711 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1712 port = physinputs[(channels_used+x)%nphysical_in];
1715 if (port.length() && track->connect_input (track->input (x), port, this)) {
1721 for (uint32_t x = 0; x < track->n_outputs().get(DataType::MIDI); ++x) {
1725 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1726 port = physoutputs[(channels_used+x)%nphysical_out];
1727 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1729 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1733 if (port.length() && track->connect_output (track->output (x), port, this)) {
1738 channels_used += track->n_inputs ().get(DataType::AUDIO);
1741 vector<string> cports;
1742 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1744 for (n = 0; n < ni; ++n) {
1745 cports.push_back (_control_out->input(n)->name());
1748 track->set_control_outs (cports);
1751 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1752 track->set_remote_control_id (ntracks());
1754 new_routes.push_back (track);
1755 ret.push_back (track);
1758 catch (failed_constructor &err) {
1759 error << _("Session: could not create new audio track.") << endmsg;
1760 // XXX should we delete the tracks already created?
1768 if (!new_routes.empty()) {
1769 add_routes (new_routes, false);
1770 save_state (_current_snapshot_name);
1777 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1780 uint32_t bus_id = 1;
1785 /* count existing audio busses */
1788 shared_ptr<RouteList> r = routes.reader ();
1790 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1791 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1792 if (!(*i)->hidden()) {
1799 vector<string> physinputs;
1800 vector<string> physoutputs;
1802 _engine.get_physical_outputs (physoutputs);
1803 _engine.get_physical_inputs (physinputs);
1810 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1812 if (route_by_name (bus_name) == 0) {
1816 } while (bus_id < (UINT_MAX-1));
1819 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1821 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1822 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1823 input_channels, output_channels)
1827 for (uint32_t x = 0; x < bus->n_inputs().get(DataType::AUDIO); ++x) {
1831 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1832 port = physinputs[((n+x)%n_physical_inputs)];
1835 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1840 for (uint32_t x = 0; x < bus->n_outputs().get(DataType::AUDIO); ++x) {
1844 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1845 port = physoutputs[((n+x)%n_physical_outputs)];
1846 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1848 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1852 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1858 vector<string> cports;
1859 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1861 for (uint32_t n = 0; n < ni; ++n) {
1862 cports.push_back (_control_out->input(n)->name());
1864 bus->set_control_outs (cports);
1867 ret.push_back (bus);
1871 catch (failed_constructor &err) {
1872 error << _("Session: could not create new audio route.") << endmsg;
1881 add_routes (ret, false);
1882 save_state (_current_snapshot_name);
1890 Session::add_routes (RouteList& new_routes, bool save)
1893 RCUWriter<RouteList> writer (routes);
1894 shared_ptr<RouteList> r = writer.get_copy ();
1895 r->insert (r->end(), new_routes.begin(), new_routes.end());
1896 resort_routes_using (r);
1899 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1901 boost::weak_ptr<Route> wpr (*x);
1903 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1904 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1905 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1906 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1908 if ((*x)->master()) {
1912 if ((*x)->control()) {
1913 _control_out = (*x);
1920 save_state (_current_snapshot_name);
1923 RouteAdded (new_routes); /* EMIT SIGNAL */
1927 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1929 /* need to do this in case we're rolling at the time, to prevent false underruns */
1930 dstream->do_refill_with_alloc();
1933 RCUWriter<DiskstreamList> writer (diskstreams);
1934 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1935 ds->push_back (dstream);
1938 dstream->set_block_size (current_block_size);
1940 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1941 /* this will connect to future changes, and check the current length */
1942 diskstream_playlist_changed (dstream);
1944 dstream->prepare ();
1948 Session::remove_route (shared_ptr<Route> route)
1951 RCUWriter<RouteList> writer (routes);
1952 shared_ptr<RouteList> rs = writer.get_copy ();
1955 /* deleting the master out seems like a dumb
1956 idea, but its more of a UI policy issue
1960 if (route == _master_out) {
1961 _master_out = shared_ptr<Route> ();
1964 if (route == _control_out) {
1965 _control_out = shared_ptr<Route> ();
1967 /* cancel control outs for all routes */
1969 vector<string> empty;
1971 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1972 (*r)->set_control_outs (empty);
1976 update_route_solo_state ();
1978 /* writer goes out of scope, forces route list update */
1982 boost::shared_ptr<Diskstream> ds;
1984 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
1985 ds = t->diskstream();
1991 RCUWriter<DiskstreamList> dsl (diskstreams);
1992 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1997 find_current_end ();
1999 update_latency_compensation (false, false);
2002 // We need to disconnect the routes inputs and outputs
2003 route->disconnect_inputs(NULL);
2004 route->disconnect_outputs(NULL);
2006 /* get rid of it from the dead wood collection in the route list manager */
2008 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2012 /* try to cause everyone to drop their references */
2014 route->drop_references ();
2016 /* save the new state of the world */
2018 if (save_state (_current_snapshot_name)) {
2019 save_history (_current_snapshot_name);
2024 Session::route_mute_changed (void* src)
2030 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2032 if (solo_update_disabled) {
2038 boost::shared_ptr<Route> route = wpr.lock ();
2041 /* should not happen */
2042 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2046 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2048 shared_ptr<RouteList> r = routes.reader ();
2050 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2052 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2056 /* don't mess with busses */
2058 if (dynamic_cast<Track*>((*i).get()) == 0) {
2064 /* don't mess with tracks */
2066 if (dynamic_cast<Track*>((*i).get()) != 0) {
2071 if ((*i) != route &&
2072 ((*i)->mix_group () == 0 ||
2073 (*i)->mix_group () != route->mix_group () ||
2074 !route->mix_group ()->is_active())) {
2076 if ((*i)->soloed()) {
2078 /* if its already soloed, and solo latching is enabled,
2079 then leave it as it is.
2082 if (Config->get_solo_latched()) {
2089 solo_update_disabled = true;
2090 (*i)->set_solo (false, src);
2091 solo_update_disabled = false;
2095 bool something_soloed = false;
2096 bool same_thing_soloed = false;
2097 bool signal = false;
2099 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2100 if ((*i)->soloed()) {
2101 something_soloed = true;
2102 if (dynamic_cast<Track*>((*i).get())) {
2104 same_thing_soloed = true;
2109 same_thing_soloed = true;
2117 if (something_soloed != currently_soloing) {
2119 currently_soloing = something_soloed;
2122 modify_solo_mute (is_track, same_thing_soloed);
2125 SoloActive (currently_soloing);
2132 Session::update_route_solo_state ()
2135 bool is_track = false;
2136 bool signal = false;
2138 /* caller must hold RouteLock */
2140 /* this is where we actually implement solo by changing
2141 the solo mute setting of each track.
2144 shared_ptr<RouteList> r = routes.reader ();
2146 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2147 if ((*i)->soloed()) {
2149 if (dynamic_cast<Track*>((*i).get())) {
2156 if (mute != currently_soloing) {
2158 currently_soloing = mute;
2161 if (!is_track && !mute) {
2163 /* nothing is soloed */
2165 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2166 (*i)->set_solo_mute (false);
2176 modify_solo_mute (is_track, mute);
2179 SoloActive (currently_soloing);
2184 Session::modify_solo_mute (bool is_track, bool mute)
2186 shared_ptr<RouteList> r = routes.reader ();
2188 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2192 /* only alter track solo mute */
2194 if (dynamic_cast<Track*>((*i).get())) {
2195 if ((*i)->soloed()) {
2196 (*i)->set_solo_mute (!mute);
2198 (*i)->set_solo_mute (mute);
2204 /* only alter bus solo mute */
2206 if (!dynamic_cast<Track*>((*i).get())) {
2208 if ((*i)->soloed()) {
2210 (*i)->set_solo_mute (false);
2214 /* don't mute master or control outs
2215 in response to another bus solo
2218 if ((*i) != _master_out &&
2219 (*i) != _control_out) {
2220 (*i)->set_solo_mute (mute);
2231 Session::catch_up_on_solo ()
2233 /* this is called after set_state() to catch the full solo
2234 state, which can't be correctly determined on a per-route
2235 basis, but needs the global overview that only the session
2238 update_route_solo_state();
2242 Session::route_by_name (string name)
2244 shared_ptr<RouteList> r = routes.reader ();
2246 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2247 if ((*i)->name() == name) {
2252 return shared_ptr<Route> ((Route*) 0);
2256 Session::route_by_id (PBD::ID id)
2258 shared_ptr<RouteList> r = routes.reader ();
2260 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2261 if ((*i)->id() == id) {
2266 return shared_ptr<Route> ((Route*) 0);
2270 Session::route_by_remote_id (uint32_t id)
2272 shared_ptr<RouteList> r = routes.reader ();
2274 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2275 if ((*i)->remote_control_id() == id) {
2280 return shared_ptr<Route> ((Route*) 0);
2284 Session::find_current_end ()
2286 if (_state_of_the_state & Loading) {
2290 nframes_t max = get_maximum_extent ();
2292 if (max > end_location->end()) {
2293 end_location->set_end (max);
2295 DurationChanged(); /* EMIT SIGNAL */
2300 Session::get_maximum_extent () const
2305 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2307 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2308 Playlist* pl = (*i)->playlist();
2309 if ((me = pl->get_maximum_extent()) > max) {
2317 boost::shared_ptr<Diskstream>
2318 Session::diskstream_by_name (string name)
2320 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2322 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2323 if ((*i)->name() == name) {
2328 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2331 boost::shared_ptr<Diskstream>
2332 Session::diskstream_by_id (const PBD::ID& id)
2334 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2336 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2337 if ((*i)->id() == id) {
2342 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2345 /* Region management */
2348 Session::new_region_name (string old)
2350 string::size_type last_period;
2352 string::size_type len = old.length() + 64;
2355 if ((last_period = old.find_last_of ('.')) == string::npos) {
2357 /* no period present - add one explicitly */
2360 last_period = old.length() - 1;
2365 number = atoi (old.substr (last_period+1).c_str());
2369 while (number < (UINT_MAX-1)) {
2371 RegionList::const_iterator i;
2376 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2379 for (i = regions.begin(); i != regions.end(); ++i) {
2380 if (i->second->name() == sbuf) {
2385 if (i == regions.end()) {
2390 if (number != (UINT_MAX-1)) {
2394 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2399 Session::region_name (string& result, string base, bool newlevel) const
2404 assert(base.find("/") == string::npos);
2408 Glib::Mutex::Lock lm (region_lock);
2410 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2418 /* XXX this is going to be slow. optimize me later */
2423 string::size_type pos;
2425 pos = base.find_last_of ('.');
2427 /* pos may be npos, but then we just use entire base */
2429 subbase = base.substr (0, pos);
2433 bool name_taken = true;
2436 Glib::Mutex::Lock lm (region_lock);
2438 for (int n = 1; n < 5000; ++n) {
2441 snprintf (buf, sizeof (buf), ".%d", n);
2446 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2447 if (i->second->name() == result) {
2460 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2468 Session::add_region (boost::shared_ptr<Region> region)
2470 boost::shared_ptr<Region> other;
2474 Glib::Mutex::Lock lm (region_lock);
2476 RegionList::iterator x;
2478 for (x = regions.begin(); x != regions.end(); ++x) {
2482 if (region->region_list_equivalent (other)) {
2487 if (x == regions.end()) {
2489 pair<RegionList::key_type,RegionList::mapped_type> entry;
2491 entry.first = region->id();
2492 entry.second = region;
2494 pair<RegionList::iterator,bool> x = regions.insert (entry);
2506 /* mark dirty because something has changed even if we didn't
2507 add the region to the region list.
2513 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2514 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2515 RegionAdded (region); /* EMIT SIGNAL */
2520 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2522 boost::shared_ptr<Region> region (weak_region.lock ());
2528 if (what_changed & Region::HiddenChanged) {
2529 /* relay hidden changes */
2530 RegionHiddenChange (region);
2535 Session::remove_region (boost::weak_ptr<Region> weak_region)
2537 RegionList::iterator i;
2538 boost::shared_ptr<Region> region (weak_region.lock ());
2544 bool removed = false;
2547 Glib::Mutex::Lock lm (region_lock);
2549 if ((i = regions.find (region->id())) != regions.end()) {
2555 /* mark dirty because something has changed even if we didn't
2556 remove the region from the region list.
2562 RegionRemoved(region); /* EMIT SIGNAL */
2566 boost::shared_ptr<Region>
2567 Session::find_whole_file_parent (Region& child)
2569 RegionList::iterator i;
2570 boost::shared_ptr<Region> region;
2572 Glib::Mutex::Lock lm (region_lock);
2574 for (i = regions.begin(); i != regions.end(); ++i) {
2578 if (region->whole_file()) {
2580 if (child.source_equivalent (region)) {
2586 return boost::shared_ptr<AudioRegion> ();
2590 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2592 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2593 (*i)->get_region_list_equivalent_regions (region, result);
2597 Session::destroy_region (boost::shared_ptr<Region> region)
2599 boost::shared_ptr<AudioRegion> aregion;
2601 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2605 if (aregion->playlist()) {
2606 aregion->playlist()->destroy_region (region);
2609 vector<boost::shared_ptr<Source> > srcs;
2611 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2612 srcs.push_back (aregion->source (n));
2615 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2617 if ((*i).use_count() == 1) {
2618 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2621 (afs)->mark_for_remove ();
2624 (*i)->drop_references ();
2632 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2634 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2635 destroy_region (*i);
2641 Session::remove_last_capture ()
2643 list<boost::shared_ptr<Region> > r;
2645 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2647 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2648 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2651 r.insert (r.end(), l.begin(), l.end());
2656 destroy_regions (r);
2661 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2667 /* Source Management */
2669 Session::add_source (boost::shared_ptr<Source> source)
2671 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2672 pair<SourceMap::iterator,bool> result;
2674 entry.first = source->id();
2675 entry.second = source;
2678 Glib::Mutex::Lock lm (source_lock);
2679 result = sources.insert (entry);
2682 if (!result.second) {
2683 cerr << "\tNOT inserted ? " << result.second << endl;
2686 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2689 SourceAdded (source); /* EMIT SIGNAL */
2693 Session::remove_source (boost::weak_ptr<Source> src)
2695 SourceMap::iterator i;
2696 boost::shared_ptr<Source> source = src.lock();
2703 Glib::Mutex::Lock lm (source_lock);
2706 Glib::Mutex::Lock lm (source_lock);
2708 if ((i = sources.find (source->id())) != sources.end()) {
2714 if (!_state_of_the_state & InCleanup) {
2716 /* save state so we don't end up with a session file
2717 referring to non-existent sources.
2720 save_state (_current_snapshot_name);
2723 SourceRemoved(source); /* EMIT SIGNAL */
2726 boost::shared_ptr<Source>
2727 Session::source_by_id (const PBD::ID& id)
2729 Glib::Mutex::Lock lm (source_lock);
2730 SourceMap::iterator i;
2731 boost::shared_ptr<Source> source;
2733 if ((i = sources.find (id)) != sources.end()) {
2737 /* XXX search MIDI or other searches here */
2743 Session::peak_path_from_audio_path (string audio_path) const
2748 res += PBD::basename_nosuffix (audio_path);
2755 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2758 string old_basename = PBD::basename_nosuffix (oldname);
2759 string new_legalized = legalize_for_path (newname);
2761 /* note: we know (or assume) the old path is already valid */
2765 /* destructive file sources have a name of the form:
2767 /path/to/Tnnnn-NAME(%[LR])?.wav
2769 the task here is to replace NAME with the new name.
2772 /* find last slash */
2776 string::size_type slash;
2777 string::size_type dash;
2779 if ((slash = path.find_last_of ('/')) == string::npos) {
2783 dir = path.substr (0, slash+1);
2785 /* '-' is not a legal character for the NAME part of the path */
2787 if ((dash = path.find_last_of ('-')) == string::npos) {
2791 prefix = path.substr (slash+1, dash-(slash+1));
2796 path += new_legalized;
2797 path += ".wav"; /* XXX gag me with a spoon */
2801 /* non-destructive file sources have a name of the form:
2803 /path/to/NAME-nnnnn(%[LR])?.wav
2805 the task here is to replace NAME with the new name.
2810 string::size_type slash;
2811 string::size_type dash;
2812 string::size_type postfix;
2814 /* find last slash */
2816 if ((slash = path.find_last_of ('/')) == string::npos) {
2820 dir = path.substr (0, slash+1);
2822 /* '-' is not a legal character for the NAME part of the path */
2824 if ((dash = path.find_last_of ('-')) == string::npos) {
2828 suffix = path.substr (dash+1);
2830 // Suffix is now everything after the dash. Now we need to eliminate
2831 // the nnnnn part, which is done by either finding a '%' or a '.'
2833 postfix = suffix.find_last_of ("%");
2834 if (postfix == string::npos) {
2835 postfix = suffix.find_last_of ('.');
2838 if (postfix != string::npos) {
2839 suffix = suffix.substr (postfix);
2841 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2845 const uint32_t limit = 10000;
2846 char buf[PATH_MAX+1];
2848 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2850 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2852 if (access (buf, F_OK) != 0) {
2860 error << "FATAL ERROR! Could not find a " << endl;
2869 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2873 char buf[PATH_MAX+1];
2874 const uint32_t limit = 10000;
2878 legalized = legalize_for_path (name);
2880 /* find a "version" of the file name that doesn't exist in
2881 any of the possible directories.
2884 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2886 vector<space_and_path>::iterator i;
2887 uint32_t existing = 0;
2889 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2893 spath += sound_dir (false);
2897 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2898 } else if (nchan == 2) {
2900 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2902 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2904 } else if (nchan < 26) {
2905 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2907 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2915 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2916 } else if (nchan == 2) {
2918 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2920 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2922 } else if (nchan < 26) {
2923 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2925 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2929 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2935 if (existing == 0) {
2940 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2941 throw failed_constructor();
2945 /* we now have a unique name for the file, but figure out where to
2951 spath = discover_best_sound_dir ();
2953 string::size_type pos = foo.find_last_of ('/');
2955 if (pos == string::npos) {
2958 spath += foo.substr (pos + 1);
2964 boost::shared_ptr<AudioFileSource>
2965 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2967 string spath = audio_path_from_name (ds.name(), ds.n_channels().get(DataType::AUDIO), chan, destructive);
2968 return boost::dynamic_pointer_cast<AudioFileSource> (
2969 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
2972 // FIXME: _terrible_ code duplication
2974 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
2977 string old_basename = PBD::basename_nosuffix (oldname);
2978 string new_legalized = legalize_for_path (newname);
2980 /* note: we know (or assume) the old path is already valid */
2984 /* destructive file sources have a name of the form:
2986 /path/to/Tnnnn-NAME(%[LR])?.wav
2988 the task here is to replace NAME with the new name.
2991 /* find last slash */
2995 string::size_type slash;
2996 string::size_type dash;
2998 if ((slash = path.find_last_of ('/')) == string::npos) {
3002 dir = path.substr (0, slash+1);
3004 /* '-' is not a legal character for the NAME part of the path */
3006 if ((dash = path.find_last_of ('-')) == string::npos) {
3010 prefix = path.substr (slash+1, dash-(slash+1));
3015 path += new_legalized;
3016 path += ".mid"; /* XXX gag me with a spoon */
3020 /* non-destructive file sources have a name of the form:
3022 /path/to/NAME-nnnnn(%[LR])?.wav
3024 the task here is to replace NAME with the new name.
3029 string::size_type slash;
3030 string::size_type dash;
3031 string::size_type postfix;
3033 /* find last slash */
3035 if ((slash = path.find_last_of ('/')) == string::npos) {
3039 dir = path.substr (0, slash+1);
3041 /* '-' is not a legal character for the NAME part of the path */
3043 if ((dash = path.find_last_of ('-')) == string::npos) {
3047 suffix = path.substr (dash+1);
3049 // Suffix is now everything after the dash. Now we need to eliminate
3050 // the nnnnn part, which is done by either finding a '%' or a '.'
3052 postfix = suffix.find_last_of ("%");
3053 if (postfix == string::npos) {
3054 postfix = suffix.find_last_of ('.');
3057 if (postfix != string::npos) {
3058 suffix = suffix.substr (postfix);
3060 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3064 const uint32_t limit = 10000;
3065 char buf[PATH_MAX+1];
3067 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3069 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3071 if (access (buf, F_OK) != 0) {
3079 error << "FATAL ERROR! Could not find a " << endl;
3088 Session::midi_path_from_name (string name)
3092 char buf[PATH_MAX+1];
3093 const uint32_t limit = 10000;
3097 legalized = legalize_for_path (name);
3099 /* find a "version" of the file name that doesn't exist in
3100 any of the possible directories.
3103 for (cnt = 1; cnt <= limit; ++cnt) {
3105 vector<space_and_path>::iterator i;
3106 uint32_t existing = 0;
3108 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3110 // FIXME: different directory from audio?
3111 spath = (*i).path + sound_dir_name + "/" + legalized;
3113 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3115 if (access (buf, F_OK) == 0) {
3120 if (existing == 0) {
3125 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3126 throw failed_constructor();
3130 /* we now have a unique name for the file, but figure out where to
3136 // FIXME: different directory than audio?
3137 spath = discover_best_sound_dir ();
3139 string::size_type pos = foo.find_last_of ('/');
3141 if (pos == string::npos) {
3144 spath += foo.substr (pos + 1);
3150 boost::shared_ptr<MidiSource>
3151 Session::create_midi_source_for_session (MidiDiskstream& ds)
3153 string spath = midi_path_from_name (ds.name());
3155 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
3159 /* Playlist management */
3162 Session::playlist_by_name (string name)
3164 Glib::Mutex::Lock lm (playlist_lock);
3165 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3166 if ((*i)->name() == name) {
3170 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3171 if ((*i)->name() == name) {
3179 Session::add_playlist (Playlist* playlist)
3181 if (playlist->hidden()) {
3186 Glib::Mutex::Lock lm (playlist_lock);
3187 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3188 playlists.insert (playlists.begin(), playlist);
3190 playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
3191 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
3197 PlaylistAdded (playlist); /* EMIT SIGNAL */
3201 Session::track_playlist (Playlist* pl, bool inuse)
3203 PlaylistList::iterator x;
3206 Glib::Mutex::Lock lm (playlist_lock);
3209 //cerr << "shifting playlist to unused: " << pl->name() << endl;
3211 unused_playlists.insert (pl);
3213 if ((x = playlists.find (pl)) != playlists.end()) {
3214 playlists.erase (x);
3219 //cerr << "shifting playlist to used: " << pl->name() << endl;
3221 playlists.insert (pl);
3223 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3224 unused_playlists.erase (x);
3231 Session::remove_playlist (Playlist* playlist)
3233 if (_state_of_the_state & Deletion) {
3238 Glib::Mutex::Lock lm (playlist_lock);
3239 // cerr << "removing playlist: " << playlist->name() << endl;
3241 PlaylistList::iterator i;
3243 i = find (playlists.begin(), playlists.end(), playlist);
3245 if (i != playlists.end()) {
3246 playlists.erase (i);
3249 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3250 if (i != unused_playlists.end()) {
3251 unused_playlists.erase (i);
3258 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3262 Session::set_audition (boost::shared_ptr<Region> r)
3264 pending_audition_region = r;
3265 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3266 schedule_butler_transport_work ();
3270 Session::audition_playlist ()
3272 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3273 ev->region.reset ();
3278 Session::non_realtime_set_audition ()
3280 if (!pending_audition_region) {
3281 auditioner->audition_current_playlist ();
3283 auditioner->audition_region (pending_audition_region);
3284 pending_audition_region.reset ();
3286 AuditionActive (true); /* EMIT SIGNAL */
3290 Session::audition_region (boost::shared_ptr<Region> r)
3292 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3298 Session::cancel_audition ()
3300 if (auditioner->active()) {
3301 auditioner->cancel_audition ();
3302 AuditionActive (false); /* EMIT SIGNAL */
3307 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3309 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3313 Session::remove_empty_sounds ()
3315 PathScanner scanner;
3317 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3319 Glib::Mutex::Lock lm (source_lock);
3321 regex_t compiled_tape_track_pattern;
3324 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3328 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3330 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3334 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3336 /* never remove files that appear to be a tape track */
3338 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3343 if (AudioFileSource::is_empty (*this, *(*i))) {
3345 unlink ((*i)->c_str());
3347 string peak_path = peak_path_from_audio_path (**i);
3348 unlink (peak_path.c_str());
3354 delete possible_audiofiles;
3358 Session::is_auditioning () const
3360 /* can be called before we have an auditioner object */
3362 return auditioner->active();
3369 Session::set_all_solo (bool yn)
3371 shared_ptr<RouteList> r = routes.reader ();
3373 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3374 if (!(*i)->hidden()) {
3375 (*i)->set_solo (yn, this);
3383 Session::set_all_mute (bool yn)
3385 shared_ptr<RouteList> r = routes.reader ();
3387 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3388 if (!(*i)->hidden()) {
3389 (*i)->set_mute (yn, this);
3397 Session::n_diskstreams () const
3401 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3403 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3404 if (!(*i)->hidden()) {
3412 Session::graph_reordered ()
3414 /* don't do this stuff if we are setting up connections
3415 from a set_state() call.
3418 if (_state_of_the_state & InitialConnecting) {
3424 /* force all diskstreams to update their capture offset values to
3425 reflect any changes in latencies within the graph.
3428 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3430 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3431 (*i)->set_capture_offset ();
3436 Session::record_disenable_all ()
3438 record_enable_change_all (false);
3442 Session::record_enable_all ()
3444 record_enable_change_all (true);
3448 Session::record_enable_change_all (bool yn)
3450 shared_ptr<RouteList> r = routes.reader ();
3452 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3455 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3456 at->set_record_enable (yn, this);
3460 /* since we don't keep rec-enable state, don't mark session dirty */
3464 Session::add_redirect (Redirect* redirect)
3468 PortInsert* port_insert;
3469 PluginInsert* plugin_insert;
3471 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3472 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3473 _port_inserts.insert (_port_inserts.begin(), port_insert);
3474 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3475 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3477 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3480 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3481 _sends.insert (_sends.begin(), send);
3483 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3487 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3493 Session::remove_redirect (Redirect* redirect)
3497 PortInsert* port_insert;
3498 PluginInsert* plugin_insert;
3500 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3501 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3502 _port_inserts.remove (port_insert);
3503 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3504 _plugin_inserts.remove (plugin_insert);
3506 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3509 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3510 _sends.remove (send);
3512 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3520 Session::available_capture_duration ()
3522 float sample_bytes_on_disk;
3524 switch (Config->get_native_file_data_format()) {
3526 sample_bytes_on_disk = 4;
3530 sample_bytes_on_disk = 3;
3534 double scale = 4096.0 / sample_bytes_on_disk;
3536 if (_total_free_4k_blocks * scale > (double) max_frames) {
3540 return (nframes_t) floor (_total_free_4k_blocks * scale);
3544 Session::add_connection (ARDOUR::Connection* connection)
3547 Glib::Mutex::Lock guard (connection_lock);
3548 _connections.push_back (connection);
3551 ConnectionAdded (connection); /* EMIT SIGNAL */
3557 Session::remove_connection (ARDOUR::Connection* connection)
3559 bool removed = false;
3562 Glib::Mutex::Lock guard (connection_lock);
3563 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3565 if (i != _connections.end()) {
3566 _connections.erase (i);
3572 ConnectionRemoved (connection); /* EMIT SIGNAL */
3578 ARDOUR::Connection *
3579 Session::connection_by_name (string name) const
3581 Glib::Mutex::Lock lm (connection_lock);
3583 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3584 if ((*i)->name() == name) {
3593 Session::tempo_map_changed (Change ignored)
3599 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3600 * the given count with the current block size.
3603 Session::ensure_buffers (ChanCount howmany)
3605 // FIXME: NASTY assumption (midi block size == audio block size)
3606 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3607 _send_buffers->ensure_buffers(howmany, current_block_size);
3608 _silent_buffers->ensure_buffers(howmany, current_block_size);
3610 allocate_pan_automation_buffers (current_block_size, howmany.get(DataType::AUDIO), false);
3614 Session::next_send_name ()
3617 snprintf (buf, sizeof (buf), "send %" PRIu32, ++send_cnt);
3622 Session::next_insert_name ()
3625 snprintf (buf, sizeof (buf), "insert %" PRIu32, ++insert_cnt);
3629 /* Named Selection management */
3632 Session::named_selection_by_name (string name)
3634 Glib::Mutex::Lock lm (named_selection_lock);
3635 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3636 if ((*i)->name == name) {
3644 Session::add_named_selection (NamedSelection* named_selection)
3647 Glib::Mutex::Lock lm (named_selection_lock);
3648 named_selections.insert (named_selections.begin(), named_selection);
3653 NamedSelectionAdded (); /* EMIT SIGNAL */
3657 Session::remove_named_selection (NamedSelection* named_selection)
3659 bool removed = false;
3662 Glib::Mutex::Lock lm (named_selection_lock);
3664 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3666 if (i != named_selections.end()) {
3668 named_selections.erase (i);
3675 NamedSelectionRemoved (); /* EMIT SIGNAL */
3680 Session::reset_native_file_format ()
3682 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3684 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3685 (*i)->reset_write_sources (false);
3690 Session::route_name_unique (string n) const
3692 shared_ptr<RouteList> r = routes.reader ();
3694 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3695 if ((*i)->name() == n) {
3704 Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
3706 return fs->move_to_trash (dead_sound_dir_name);
3710 Session::n_playlists () const
3712 Glib::Mutex::Lock lm (playlist_lock);
3713 return playlists.size();
3717 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3719 if (!force && howmany <= _npan_buffers) {
3723 if (_pan_automation_buffer) {
3725 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3726 delete [] _pan_automation_buffer[i];
3729 delete [] _pan_automation_buffer;
3732 _pan_automation_buffer = new pan_t*[howmany];
3734 for (uint32_t i = 0; i < howmany; ++i) {
3735 _pan_automation_buffer[i] = new pan_t[nframes];
3738 _npan_buffers = howmany;
3742 Session::freeze (InterThreadInfo& itt)
3744 shared_ptr<RouteList> r = routes.reader ();
3746 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3750 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3751 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3762 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3763 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3765 boost::shared_ptr<AudioFileSource> fsource;
3768 Playlist* playlist = 0;
3770 char buf[PATH_MAX+1];
3772 ChanCount nchans(track.audio_diskstream()->n_channels());
3773 jack_nframes_t position;
3774 jack_nframes_t this_chunk;
3775 jack_nframes_t to_do;
3778 // any bigger than this seems to cause stack overflows in called functions
3779 const nframes_t chunk_size = (128 * 1024)/4;
3781 g_atomic_int_set (&processing_prohibited, 1);
3783 /* call tree *MUST* hold route_lock */
3785 if ((playlist = track.diskstream()->playlist()) == 0) {
3789 /* external redirects will be a problem */
3791 if (track.has_external_redirects()) {
3795 dir = discover_best_sound_dir ();
3797 for (uint32_t chan_n=0; chan_n < nchans.get(DataType::AUDIO); ++chan_n) {
3799 for (x = 0; x < 99999; ++x) {
3800 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3801 if (access (buf, F_OK) != 0) {
3807 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3812 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3813 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3816 catch (failed_constructor& err) {
3817 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3821 srcs.push_back (fsource);
3824 /* XXX need to flush all redirects */
3829 /* create a set of reasonably-sized buffers */
3830 buffers.ensure_buffers(nchans, chunk_size);
3831 buffers.set_count(nchans);
3833 while (to_do && !itt.cancel) {
3835 this_chunk = min (to_do, chunk_size);
3837 if (track.export_stuff (buffers, start, this_chunk)) {
3842 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3843 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3846 if (afs->write (buffers.get_audio(n).data(this_chunk), this_chunk) != this_chunk) {
3852 start += this_chunk;
3853 to_do -= this_chunk;
3855 itt.progress = (float) (1.0 - ((double) to_do / len));
3864 xnow = localtime (&now);
3866 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3867 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3870 afs->update_header (position, *xnow, now);
3874 /* build peakfile for new source */
3876 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3877 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3879 afs->build_peaks ();
3883 /* construct a region to represent the bounced material */
3885 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3886 region_name_from_path (srcs.front()->name()));
3893 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3894 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3897 afs->mark_for_remove ();
3900 (*src)->drop_references ();
3904 g_atomic_int_set (&processing_prohibited, 0);
3912 Session::get_silent_buffers (ChanCount count)
3914 assert(_silent_buffers->available() >= count);
3915 _silent_buffers->set_count(count);
3917 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3918 for (size_t i=0; i < count.get(*t); ++i) {
3919 _silent_buffers->get(*t, i).clear();
3923 return *_silent_buffers;
3927 Session::get_scratch_buffers (ChanCount count)
3929 assert(_scratch_buffers->available() >= count);
3930 _scratch_buffers->set_count(count);
3931 return *_scratch_buffers;
3935 Session::get_send_buffers (ChanCount count)
3937 assert(_send_buffers->available() >= count);
3938 _send_buffers->set_count(count);
3939 return *_send_buffers;
3943 Session::ntracks () const
3946 shared_ptr<RouteList> r = routes.reader ();
3948 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3949 if (dynamic_cast<Track*> ((*i).get())) {
3958 Session::nbusses () const
3961 shared_ptr<RouteList> r = routes.reader ();
3963 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3964 if (dynamic_cast<Track*> ((*i).get()) == 0) {
3973 Session::add_curve(Curve *curve)
3975 curves[curve->id()] = curve;
3979 Session::add_automation_list(AutomationList *al)
3981 automation_lists[al->id()] = al;