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>
43 #include <pbd/stacktrace.h>
45 #include <ardour/audioengine.h>
46 #include <ardour/configuration.h>
47 #include <ardour/session.h>
48 #include <ardour/utils.h>
49 #include <ardour/audio_diskstream.h>
50 #include <ardour/audioplaylist.h>
51 #include <ardour/audioregion.h>
52 #include <ardour/audiofilesource.h>
53 #include <ardour/midi_diskstream.h>
54 #include <ardour/midi_playlist.h>
55 #include <ardour/midi_region.h>
56 #include <ardour/smf_source.h>
57 #include <ardour/destructive_filesource.h>
58 #include <ardour/auditioner.h>
59 #include <ardour/recent_sessions.h>
60 #include <ardour/redirect.h>
61 #include <ardour/send.h>
62 #include <ardour/insert.h>
63 #include <ardour/connection.h>
64 #include <ardour/slave.h>
65 #include <ardour/tempo.h>
66 #include <ardour/audio_track.h>
67 #include <ardour/midi_track.h>
68 #include <ardour/cycle_timer.h>
69 #include <ardour/named_selection.h>
70 #include <ardour/crossfade.h>
71 #include <ardour/playlist.h>
72 #include <ardour/click.h>
73 #include <ardour/data_type.h>
74 #include <ardour/buffer_set.h>
75 #include <ardour/source_factory.h>
76 #include <ardour/region_factory.h>
79 #include <ardour/osc.h>
85 using namespace ARDOUR;
87 using boost::shared_ptr;
89 const char* Session::_template_suffix = X_(".template");
90 const char* Session::_statefile_suffix = X_(".ardour");
91 const char* Session::_pending_suffix = X_(".pending");
92 const char* Session::old_sound_dir_name = X_("sounds");
93 const char* Session::sound_dir_name = X_("audiofiles");
94 const char* Session::peak_dir_name = X_("peaks");
95 const char* Session::dead_sound_dir_name = X_("dead_sounds");
96 const char* Session::interchange_dir_name = X_("interchange");
98 Session::compute_peak_t Session::compute_peak = 0;
99 Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0;
100 Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
101 Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
103 sigc::signal<int> Session::AskAboutPendingState;
104 sigc::signal<void> Session::SendFeedback;
106 sigc::signal<void> Session::SMPTEOffsetChanged;
107 sigc::signal<void> Session::StartTimeChanged;
108 sigc::signal<void> Session::EndTimeChanged;
111 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
114 char buf[PATH_MAX+1];
118 if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) {
119 error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg;
125 /* check to see if it exists, and what it is */
127 if (stat (str.c_str(), &statbuf)) {
128 if (errno == ENOENT) {
131 error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno))
139 /* it exists, so it must either be the name
140 of the directory, or the name of the statefile
144 if (S_ISDIR (statbuf.st_mode)) {
146 string::size_type slash = str.find_last_of ('/');
148 if (slash == string::npos) {
150 /* a subdirectory of cwd, so statefile should be ... */
156 tmp += _statefile_suffix;
160 if (stat (tmp.c_str(), &statbuf)) {
161 error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno))
171 /* some directory someplace in the filesystem.
172 the snapshot name is the directory name
177 snapshot = str.substr (slash+1);
181 } else if (S_ISREG (statbuf.st_mode)) {
183 string::size_type slash = str.find_last_of ('/');
184 string::size_type suffix;
186 /* remove the suffix */
188 if (slash != string::npos) {
189 snapshot = str.substr (slash+1);
194 suffix = snapshot.find (_statefile_suffix);
196 if (suffix == string::npos) {
197 error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg;
203 snapshot = snapshot.substr (0, suffix);
205 if (slash == string::npos) {
207 /* we must be in the directory where the
208 statefile lives. get it using cwd().
211 char cwd[PATH_MAX+1];
213 if (getcwd (cwd, sizeof (cwd)) == 0) {
214 error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno))
223 /* full path to the statefile */
225 path = str.substr (0, slash);
230 /* what type of file is it? */
231 error << string_compose (_("unknown file type for session %1"), str) << endmsg;
237 /* its the name of a new directory. get the name
241 string::size_type slash = str.find_last_of ('/');
243 if (slash == string::npos) {
245 /* no slash, just use the name, but clean it up */
247 path = legalize_for_path (str);
253 snapshot = str.substr (slash+1);
260 Session::Session (AudioEngine &eng,
262 string snapshot_name,
263 string* mix_template)
266 _scratch_buffers(new BufferSet()),
267 _silent_buffers(new BufferSet()),
268 _send_buffers(new BufferSet()),
269 _mmc_port (default_mmc_port),
270 _mtc_port (default_mtc_port),
271 _midi_port (default_midi_port),
272 pending_events (2048),
273 //midi_requests (128), // the size of this should match the midi request pool size
274 _send_smpte_update (false),
275 diskstreams (new DiskstreamList),
276 routes (new RouteList),
277 auditioner ((Auditioner*) 0),
283 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
285 n_physical_outputs = _engine.n_physical_outputs();
286 n_physical_inputs = _engine.n_physical_inputs();
288 first_stage_init (fullpath, snapshot_name);
290 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
292 if (create (new_session, mix_template, compute_initial_length())) {
293 cerr << "create failed\n";
295 throw failed_constructor ();
299 if (second_stage_init (new_session)) {
301 throw failed_constructor ();
304 store_recent_sessions(_name, _path);
306 bool was_dirty = dirty();
308 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
310 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
313 DirtyChanged (); /* EMIT SIGNAL */
317 Session::Session (AudioEngine &eng,
319 string snapshot_name,
320 AutoConnectOption input_ac,
321 AutoConnectOption output_ac,
322 uint32_t control_out_channels,
323 uint32_t master_out_channels,
324 uint32_t requested_physical_in,
325 uint32_t requested_physical_out,
326 nframes_t initial_length)
329 _scratch_buffers(new BufferSet()),
330 _silent_buffers(new BufferSet()),
331 _send_buffers(new BufferSet()),
332 _mmc_port (default_mmc_port),
333 _mtc_port (default_mtc_port),
334 _midi_port (default_midi_port),
335 pending_events (2048),
336 //midi_requests (16),
337 _send_smpte_update (false),
338 diskstreams (new DiskstreamList),
339 routes (new RouteList),
345 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
347 n_physical_outputs = _engine.n_physical_outputs();
348 n_physical_inputs = _engine.n_physical_inputs();
350 if (n_physical_inputs) {
351 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
354 if (n_physical_outputs) {
355 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
358 first_stage_init (fullpath, snapshot_name);
360 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
363 if (create (new_session, 0, initial_length)) {
365 throw failed_constructor ();
370 /* set up Master Out and Control Out if necessary */
375 if (control_out_channels) {
376 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
377 r->set_remote_control_id (control_id++);
382 if (master_out_channels) {
383 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
384 r->set_remote_control_id (control_id);
385 cerr << "master bus has remote control ID " << r->remote_control_id() << endl;
389 /* prohibit auto-connect to master, because there isn't one */
390 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
399 Config->set_input_auto_connect (input_ac);
400 Config->set_output_auto_connect (output_ac);
402 if (second_stage_init (new_session)) {
404 throw failed_constructor ();
407 store_recent_sessions(_name, _path);
409 bool was_dirty = dirty ();
411 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
414 DirtyChanged (); /* EMIT SIGNAL */
426 /* if we got to here, leaving pending capture state around
430 remove_pending_capture_state ();
432 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
433 _engine.remove_session ();
435 GoingAway (); /* EMIT SIGNAL */
441 /* clear history so that no references to objects are held any more */
445 /* clear state tree so that no references to objects are held any more */
451 terminate_butler_thread ();
452 //terminate_midi_thread ();
454 if (click_data && click_data != default_click) {
455 delete [] click_data;
458 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
459 delete [] click_emphasis_data;
464 delete _scratch_buffers;
465 delete _silent_buffers;
466 delete _send_buffers;
468 AudioDiskstream::free_working_buffers();
470 #undef TRACK_DESTRUCTION
471 #ifdef TRACK_DESTRUCTION
472 cerr << "delete named selections\n";
473 #endif /* TRACK_DESTRUCTION */
474 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
475 NamedSelectionList::iterator tmp;
484 #ifdef TRACK_DESTRUCTION
485 cerr << "delete playlists\n";
486 #endif /* TRACK_DESTRUCTION */
487 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
488 PlaylistList::iterator tmp;
493 (*i)->drop_references ();
498 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
499 PlaylistList::iterator tmp;
504 (*i)->drop_references ();
510 unused_playlists.clear ();
512 #ifdef TRACK_DESTRUCTION
513 cerr << "delete regions\n";
514 #endif /* TRACK_DESTRUCTION */
516 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
517 RegionList::iterator tmp;
522 cerr << "dropping refs on a region (" << i->second->name() << " @ " << i->second << ") with UC = " << i->second.use_count() << endl;
523 i->second->drop_references ();
524 cerr << "AFTER: UC = " << i->second.use_count() << endl;
531 #ifdef TRACK_DESTRUCTION
532 cerr << "delete routes\n";
533 #endif /* TRACK_DESTRUCTION */
535 RCUWriter<RouteList> writer (routes);
536 boost::shared_ptr<RouteList> r = writer.get_copy ();
537 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
538 (*i)->drop_references ();
541 /* writer goes out of scope and updates master */
546 #ifdef TRACK_DESTRUCTION
547 cerr << "delete diskstreams\n";
548 #endif /* TRACK_DESTRUCTION */
550 RCUWriter<DiskstreamList> dwriter (diskstreams);
551 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
552 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
553 (*i)->drop_references ();
557 diskstreams.flush ();
559 #ifdef TRACK_DESTRUCTION
560 cerr << "delete audio sources\n";
561 #endif /* TRACK_DESTRUCTION */
562 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
563 SourceMap::iterator tmp;
568 i->second->drop_references ();
575 #ifdef TRACK_DESTRUCTION
576 cerr << "delete mix groups\n";
577 #endif /* TRACK_DESTRUCTION */
578 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
579 list<RouteGroup*>::iterator tmp;
589 #ifdef TRACK_DESTRUCTION
590 cerr << "delete edit groups\n";
591 #endif /* TRACK_DESTRUCTION */
592 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
593 list<RouteGroup*>::iterator tmp;
603 #ifdef TRACK_DESTRUCTION
604 cerr << "delete connections\n";
605 #endif /* TRACK_DESTRUCTION */
606 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
607 ConnectionList::iterator tmp;
617 if (butler_mixdown_buffer) {
618 delete [] butler_mixdown_buffer;
621 if (butler_gain_buffer) {
622 delete [] butler_gain_buffer;
625 Crossfade::set_buffer_size (0);
633 Session::set_worst_io_latencies ()
635 _worst_output_latency = 0;
636 _worst_input_latency = 0;
638 if (!_engine.connected()) {
642 boost::shared_ptr<RouteList> r = routes.reader ();
644 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
645 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
646 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
651 Session::when_engine_running ()
653 string first_physical_output;
655 /* we don't want to run execute this again */
657 set_block_size (_engine.frames_per_cycle());
658 set_frame_rate (_engine.frame_rate());
660 Config->map_parameters (mem_fun (*this, &Session::config_changed));
662 /* every time we reconnect, recompute worst case output latencies */
664 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
666 if (synced_to_jack()) {
667 _engine.transport_stop ();
670 if (Config->get_jack_time_master()) {
671 _engine.transport_locate (_transport_frame);
679 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
681 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
683 /* existing state for Click */
685 if (_click_io->set_state (*child->children().front()) == 0) {
687 _clicking = Config->get_clicking ();
691 error << _("could not setup Click I/O") << endmsg;
697 /* default state for Click */
699 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
701 if (first_physical_output.length()) {
702 if (_click_io->add_output_port (first_physical_output, this)) {
703 // relax, even though its an error
705 _clicking = Config->get_clicking ();
711 catch (failed_constructor& err) {
712 error << _("cannot setup Click I/O") << endmsg;
715 set_worst_io_latencies ();
718 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
721 /* Create a set of Connection objects that map
722 to the physical outputs currently available
727 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
729 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
731 Connection* c = new OutputConnection (buf, true);
734 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
739 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
741 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
743 Connection* c = new InputConnection (buf, true);
746 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
753 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
755 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
757 Connection* c = new OutputConnection (buf, true);
761 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
762 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
767 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
769 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
771 Connection* c = new InputConnection (buf, true);
775 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
776 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
785 /* create master/control ports */
790 /* force the master to ignore any later call to this */
792 if (_master_out->pending_state_node) {
793 _master_out->ports_became_legal();
796 /* no panner resets till we are through */
798 _master_out->defer_pan_reset ();
800 while (_master_out->n_inputs().get(DataType::AUDIO)
801 < _master_out->input_maximum().get(DataType::AUDIO)) {
802 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
803 error << _("cannot setup master inputs")
809 while (_master_out->n_outputs().get(DataType::AUDIO)
810 < _master_out->output_maximum().get(DataType::AUDIO)) {
811 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
812 error << _("cannot setup master outputs")
819 _master_out->allow_pan_reset ();
823 Connection* c = new OutputConnection (_("Master Out"), true);
825 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
827 c->add_connection ((int) n, _master_out->input(n)->name());
834 /* catch up on send+insert cnts */
838 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
841 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
842 if (id > insert_cnt) {
850 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
853 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
861 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
863 /* hook us up to the engine */
865 _engine.set_session (this);
870 osc->set_session (*this);
873 _state_of_the_state = Clean;
875 DirtyChanged (); /* EMIT SIGNAL */
879 Session::hookup_io ()
881 /* stop graph reordering notifications from
882 causing resorts, etc.
885 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
887 if (auditioner == 0) {
889 /* we delay creating the auditioner till now because
890 it makes its own connections to ports.
891 the engine has to be running for this to work.
895 auditioner.reset (new Auditioner (*this));
898 catch (failed_constructor& err) {
899 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
903 /* Tell all IO objects to create their ports */
910 while (_control_out->n_inputs().get(DataType::AUDIO) < _control_out->input_maximum().get(DataType::AUDIO)) {
911 if (_control_out->add_input_port ("", this)) {
912 error << _("cannot setup control inputs")
918 while (_control_out->n_outputs().get(DataType::AUDIO) < _control_out->output_maximum().get(DataType::AUDIO)) {
919 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
920 error << _("cannot set up master outputs")
928 /* Tell all IO objects to connect themselves together */
930 IO::enable_connecting ();
932 /* Now reset all panners */
934 IO::reset_panners ();
936 /* Anyone who cares about input state, wake up and do something */
938 IOConnectionsComplete (); /* EMIT SIGNAL */
940 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
942 /* now handle the whole enchilada as if it was one
948 /* update mixer solo state */
954 Session::playlist_length_changed ()
956 /* we can't just increase end_location->end() if pl->get_maximum_extent()
957 if larger. if the playlist used to be the longest playlist,
958 and its now shorter, we have to decrease end_location->end(). hence,
959 we have to iterate over all diskstreams and check the
960 playlists currently in use.
966 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
968 boost::shared_ptr<Playlist> playlist;
970 if ((playlist = dstream->playlist()) != 0) {
971 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
974 /* see comment in playlist_length_changed () */
979 Session::record_enabling_legal () const
981 /* this used to be in here, but survey says.... we don't need to restrict it */
982 // if (record_status() == Recording) {
986 if (Config->get_all_safe()) {
993 Session::reset_input_monitor_state ()
995 if (transport_rolling()) {
997 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
999 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1000 if ((*i)->record_enabled ()) {
1001 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
1002 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
1006 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1008 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1009 if ((*i)->record_enabled ()) {
1010 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
1011 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
1018 Session::auto_punch_start_changed (Location* location)
1020 replace_event (Event::PunchIn, location->start());
1022 if (get_record_enabled() && Config->get_punch_in()) {
1023 /* capture start has been changed, so save new pending state */
1024 save_state ("", true);
1029 Session::auto_punch_end_changed (Location* location)
1031 nframes_t when_to_stop = location->end();
1032 // when_to_stop += _worst_output_latency + _worst_input_latency;
1033 replace_event (Event::PunchOut, when_to_stop);
1037 Session::auto_punch_changed (Location* location)
1039 nframes_t when_to_stop = location->end();
1041 replace_event (Event::PunchIn, location->start());
1042 //when_to_stop += _worst_output_latency + _worst_input_latency;
1043 replace_event (Event::PunchOut, when_to_stop);
1047 Session::auto_loop_changed (Location* location)
1049 replace_event (Event::AutoLoop, location->end(), location->start());
1051 if (transport_rolling() && play_loop) {
1053 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
1055 if (_transport_frame > location->end()) {
1056 // relocate to beginning of loop
1057 clear_events (Event::LocateRoll);
1059 request_locate (location->start(), true);
1062 else if (Config->get_seamless_loop() && !loop_changing) {
1064 // schedule a locate-roll to refill the diskstreams at the
1065 // previous loop end
1066 loop_changing = true;
1068 if (location->end() > last_loopend) {
1069 clear_events (Event::LocateRoll);
1070 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
1077 last_loopend = location->end();
1082 Session::set_auto_punch_location (Location* location)
1086 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
1087 auto_punch_start_changed_connection.disconnect();
1088 auto_punch_end_changed_connection.disconnect();
1089 auto_punch_changed_connection.disconnect();
1090 existing->set_auto_punch (false, this);
1091 remove_event (existing->start(), Event::PunchIn);
1092 clear_events (Event::PunchOut);
1093 auto_punch_location_changed (0);
1098 if (location == 0) {
1102 if (location->end() <= location->start()) {
1103 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
1107 auto_punch_start_changed_connection.disconnect();
1108 auto_punch_end_changed_connection.disconnect();
1109 auto_punch_changed_connection.disconnect();
1111 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
1112 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
1113 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
1115 location->set_auto_punch (true, this);
1116 auto_punch_location_changed (location);
1120 Session::set_auto_loop_location (Location* location)
1124 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1125 auto_loop_start_changed_connection.disconnect();
1126 auto_loop_end_changed_connection.disconnect();
1127 auto_loop_changed_connection.disconnect();
1128 existing->set_auto_loop (false, this);
1129 remove_event (existing->end(), Event::AutoLoop);
1130 auto_loop_location_changed (0);
1135 if (location == 0) {
1139 if (location->end() <= location->start()) {
1140 error << _("Session: you can't use a mark for auto loop") << endmsg;
1144 last_loopend = location->end();
1146 auto_loop_start_changed_connection.disconnect();
1147 auto_loop_end_changed_connection.disconnect();
1148 auto_loop_changed_connection.disconnect();
1150 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1151 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1152 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1154 location->set_auto_loop (true, this);
1155 auto_loop_location_changed (location);
1159 Session::locations_added (Location* ignored)
1165 Session::locations_changed ()
1167 _locations.apply (*this, &Session::handle_locations_changed);
1171 Session::handle_locations_changed (Locations::LocationList& locations)
1173 Locations::LocationList::iterator i;
1175 bool set_loop = false;
1176 bool set_punch = false;
1178 for (i = locations.begin(); i != locations.end(); ++i) {
1182 if (location->is_auto_punch()) {
1183 set_auto_punch_location (location);
1186 if (location->is_auto_loop()) {
1187 set_auto_loop_location (location);
1194 set_auto_loop_location (0);
1197 set_auto_punch_location (0);
1204 Session::enable_record ()
1206 /* XXX really atomic compare+swap here */
1207 if (g_atomic_int_get (&_record_status) != Recording) {
1208 g_atomic_int_set (&_record_status, Recording);
1209 _last_record_location = _transport_frame;
1210 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1212 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1213 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1214 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1215 if ((*i)->record_enabled ()) {
1216 (*i)->monitor_input (true);
1221 RecordStateChanged ();
1226 Session::disable_record (bool rt_context, bool force)
1230 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1232 if (!Config->get_latched_record_enable () || force) {
1233 g_atomic_int_set (&_record_status, Disabled);
1235 if (rs == Recording) {
1236 g_atomic_int_set (&_record_status, Enabled);
1240 // FIXME: timestamp correct? [DR]
1241 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1242 // does this /need/ to be sent in all cases?
1244 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1246 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1247 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1249 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1250 if ((*i)->record_enabled ()) {
1251 (*i)->monitor_input (false);
1256 RecordStateChanged (); /* emit signal */
1259 remove_pending_capture_state ();
1265 Session::step_back_from_record ()
1267 g_atomic_int_set (&_record_status, Enabled);
1269 if (Config->get_monitoring_model() == HardwareMonitoring) {
1270 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1272 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1273 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1274 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1275 (*i)->monitor_input (false);
1282 Session::maybe_enable_record ()
1284 g_atomic_int_set (&_record_status, Enabled);
1286 /* this function is currently called from somewhere other than an RT thread.
1287 this save_state() call therefore doesn't impact anything.
1290 save_state ("", true);
1292 if (_transport_speed) {
1293 if (!Config->get_punch_in()) {
1297 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1298 RecordStateChanged (); /* EMIT SIGNAL */
1305 Session::audible_frame () const
1311 /* the first of these two possible settings for "offset"
1312 mean that the audible frame is stationary until
1313 audio emerges from the latency compensation
1316 the second means that the audible frame is stationary
1317 until audio would emerge from a physical port
1318 in the absence of any plugin latency compensation
1321 offset = _worst_output_latency;
1323 if (offset > current_block_size) {
1324 offset -= current_block_size;
1326 /* XXX is this correct? if we have no external
1327 physical connections and everything is internal
1328 then surely this is zero? still, how
1329 likely is that anyway?
1331 offset = current_block_size;
1334 if (synced_to_jack()) {
1335 tf = _engine.transport_frame();
1337 tf = _transport_frame;
1340 if (_transport_speed == 0) {
1350 if (!non_realtime_work_pending()) {
1354 /* take latency into account */
1363 Session::set_frame_rate (nframes_t frames_per_second)
1365 /** \fn void Session::set_frame_size(nframes_t)
1366 the AudioEngine object that calls this guarantees
1367 that it will not be called while we are also in
1368 ::process(). Its fine to do things that block
1372 _base_frame_rate = frames_per_second;
1376 Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
1378 // XXX we need some equivalent to this, somehow
1379 // SndFileSource::setup_standard_crossfades (frames_per_second);
1383 /* XXX need to reset/reinstantiate all LADSPA plugins */
1387 Session::set_block_size (nframes_t nframes)
1389 /* the AudioEngine guarantees
1390 that it will not be called while we are also in
1391 ::process(). It is therefore fine to do things that block
1397 current_block_size = nframes;
1399 ensure_buffers(_scratch_buffers->available());
1401 if (_gain_automation_buffer) {
1402 delete [] _gain_automation_buffer;
1404 _gain_automation_buffer = new gain_t[nframes];
1406 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1408 boost::shared_ptr<RouteList> r = routes.reader ();
1410 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1411 (*i)->set_block_size (nframes);
1414 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1415 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1416 (*i)->set_block_size (nframes);
1419 set_worst_io_latencies ();
1424 Session::set_default_fade (float steepness, float fade_msecs)
1427 nframes_t fade_frames;
1429 /* Don't allow fade of less 1 frame */
1431 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1438 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1442 default_fade_msecs = fade_msecs;
1443 default_fade_steepness = steepness;
1446 // jlc, WTF is this!
1447 Glib::RWLock::ReaderLock lm (route_lock);
1448 AudioRegion::set_default_fade (steepness, fade_frames);
1453 /* XXX have to do this at some point */
1454 /* foreach region using default fade, reset, then
1455 refill_all_diskstream_buffers ();
1460 struct RouteSorter {
1461 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1462 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1464 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1467 if (r1->fed_by.empty()) {
1468 if (r2->fed_by.empty()) {
1469 /* no ardour-based connections inbound to either route. just use signal order */
1470 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1472 /* r2 has connections, r1 does not; run r1 early */
1476 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1483 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1485 shared_ptr<Route> r2;
1487 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1488 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1492 /* make a copy of the existing list of routes that feed r1 */
1494 set<shared_ptr<Route> > existing = r1->fed_by;
1496 /* for each route that feeds r1, recurse, marking it as feeding
1500 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1503 /* r2 is a route that feeds r1 which somehow feeds base. mark
1504 base as being fed by r2
1507 rbase->fed_by.insert (r2);
1511 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1515 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1519 /* now recurse, so that we can mark base as being fed by
1520 all routes that feed r2
1523 trace_terminal (r2, rbase);
1530 Session::resort_routes ()
1532 /* don't do anything here with signals emitted
1533 by Routes while we are being destroyed.
1536 if (_state_of_the_state & Deletion) {
1543 RCUWriter<RouteList> writer (routes);
1544 shared_ptr<RouteList> r = writer.get_copy ();
1545 resort_routes_using (r);
1546 /* writer goes out of scope and forces update */
1551 Session::resort_routes_using (shared_ptr<RouteList> r)
1553 RouteList::iterator i, j;
1555 for (i = r->begin(); i != r->end(); ++i) {
1557 (*i)->fed_by.clear ();
1559 for (j = r->begin(); j != r->end(); ++j) {
1561 /* although routes can feed themselves, it will
1562 cause an endless recursive descent if we
1563 detect it. so don't bother checking for
1571 if ((*j)->feeds (*i)) {
1572 (*i)->fed_by.insert (*j);
1577 for (i = r->begin(); i != r->end(); ++i) {
1578 trace_terminal (*i, *i);
1585 cerr << "finished route resort\n";
1587 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1588 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1595 list<boost::shared_ptr<MidiTrack> >
1596 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1598 char track_name[32];
1599 uint32_t track_id = 0;
1601 uint32_t channels_used = 0;
1603 RouteList new_routes;
1604 list<boost::shared_ptr<MidiTrack> > ret;
1606 /* count existing midi tracks */
1609 shared_ptr<RouteList> r = routes.reader ();
1611 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1612 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1613 if (!(*i)->hidden()) {
1615 channels_used += (*i)->n_inputs().get(DataType::MIDI);
1623 /* check for duplicate route names, since we might have pre-existing
1624 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1625 save, close,restart,add new route - first named route is now
1633 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1635 if (route_by_name (track_name) == 0) {
1639 } while (track_id < (UINT_MAX-1));
1642 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1644 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1645 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1648 channels_used += track->n_inputs ().get(DataType::MIDI);
1650 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1651 track->set_remote_control_id (ntracks());
1653 new_routes.push_back (track);
1654 ret.push_back (track);
1657 catch (failed_constructor &err) {
1658 error << _("Session: could not create new midi track.") << endmsg;
1659 // XXX should we delete the tracks already created?
1667 if (!new_routes.empty()) {
1668 add_routes (new_routes, false);
1669 save_state (_current_snapshot_name);
1675 list<boost::shared_ptr<AudioTrack> >
1676 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1678 char track_name[32];
1679 uint32_t track_id = 0;
1681 uint32_t channels_used = 0;
1683 RouteList new_routes;
1684 list<boost::shared_ptr<AudioTrack> > ret;
1685 uint32_t control_id;
1687 /* count existing audio tracks */
1690 shared_ptr<RouteList> r = routes.reader ();
1692 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1693 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1694 if (!(*i)->hidden()) {
1696 channels_used += (*i)->n_inputs().get(DataType::AUDIO);
1702 vector<string> physinputs;
1703 vector<string> physoutputs;
1704 uint32_t nphysical_in;
1705 uint32_t nphysical_out;
1707 _engine.get_physical_outputs (physoutputs);
1708 _engine.get_physical_inputs (physinputs);
1709 control_id = ntracks() + nbusses() + 1;
1713 /* check for duplicate route names, since we might have pre-existing
1714 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1715 save, close,restart,add new route - first named route is now
1723 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1725 if (route_by_name (track_name) == 0) {
1729 } while (track_id < (UINT_MAX-1));
1731 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1732 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1737 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1738 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1744 shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
1746 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1747 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1748 input_channels, output_channels)
1753 for (uint32_t x = 0; x < track->n_inputs().get(DataType::AUDIO) && x < nphysical_in; ++x) {
1757 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1758 port = physinputs[(channels_used+x)%nphysical_in];
1761 if (port.length() && track->connect_input (track->input (x), port, this)) {
1767 for (uint32_t x = 0; x < track->n_outputs().get(DataType::MIDI); ++x) {
1771 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1772 port = physoutputs[(channels_used+x)%nphysical_out];
1773 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1775 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1779 if (port.length() && track->connect_output (track->output (x), port, this)) {
1784 channels_used += track->n_inputs ().get(DataType::AUDIO);
1787 vector<string> cports;
1788 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1790 for (n = 0; n < ni; ++n) {
1791 cports.push_back (_control_out->input(n)->name());
1794 track->set_control_outs (cports);
1797 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1798 track->set_remote_control_id (control_id);
1801 new_routes.push_back (track);
1802 ret.push_back (track);
1805 catch (failed_constructor &err) {
1806 error << _("Session: could not create new audio track.") << endmsg;
1807 // XXX should we delete the tracks already created?
1815 if (!new_routes.empty()) {
1816 add_routes (new_routes, false);
1817 save_state (_current_snapshot_name);
1824 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1827 uint32_t bus_id = 1;
1831 uint32_t control_id;
1833 /* count existing audio busses */
1836 shared_ptr<RouteList> r = routes.reader ();
1838 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1839 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1840 if (!(*i)->hidden()) {
1847 vector<string> physinputs;
1848 vector<string> physoutputs;
1850 _engine.get_physical_outputs (physoutputs);
1851 _engine.get_physical_inputs (physinputs);
1852 control_id = ntracks() + nbusses() + 1;
1859 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1861 if (route_by_name (bus_name) == 0) {
1865 } while (bus_id < (UINT_MAX-1));
1868 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1870 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1871 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1872 input_channels, output_channels)
1876 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().get(DataType::AUDIO); ++x) {
1880 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1881 port = physinputs[((n+x)%n_physical_inputs)];
1884 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1889 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().get(DataType::AUDIO); ++x) {
1893 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1894 port = physoutputs[((n+x)%n_physical_outputs)];
1895 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1897 port = _master_out->input (x%_master_out->n_inputs().get(DataType::AUDIO))->name();
1901 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1907 vector<string> cports;
1908 uint32_t ni = _control_out->n_inputs().get(DataType::AUDIO);
1910 for (uint32_t n = 0; n < ni; ++n) {
1911 cports.push_back (_control_out->input(n)->name());
1913 bus->set_control_outs (cports);
1916 bus->set_remote_control_id (control_id);
1919 ret.push_back (bus);
1923 catch (failed_constructor &err) {
1924 error << _("Session: could not create new audio route.") << endmsg;
1933 add_routes (ret, false);
1934 save_state (_current_snapshot_name);
1942 Session::add_routes (RouteList& new_routes, bool save)
1945 RCUWriter<RouteList> writer (routes);
1946 shared_ptr<RouteList> r = writer.get_copy ();
1947 r->insert (r->end(), new_routes.begin(), new_routes.end());
1948 resort_routes_using (r);
1951 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1953 boost::weak_ptr<Route> wpr (*x);
1955 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1956 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1957 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1958 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1960 if ((*x)->master()) {
1964 if ((*x)->control()) {
1965 _control_out = (*x);
1972 save_state (_current_snapshot_name);
1975 RouteAdded (new_routes); /* EMIT SIGNAL */
1979 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1981 /* need to do this in case we're rolling at the time, to prevent false underruns */
1982 dstream->do_refill_with_alloc();
1985 RCUWriter<DiskstreamList> writer (diskstreams);
1986 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1987 ds->push_back (dstream);
1990 dstream->set_block_size (current_block_size);
1992 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1993 /* this will connect to future changes, and check the current length */
1994 diskstream_playlist_changed (dstream);
1996 dstream->prepare ();
2000 Session::remove_route (shared_ptr<Route> route)
2003 RCUWriter<RouteList> writer (routes);
2004 shared_ptr<RouteList> rs = writer.get_copy ();
2008 /* deleting the master out seems like a dumb
2009 idea, but its more of a UI policy issue
2013 if (route == _master_out) {
2014 _master_out = shared_ptr<Route> ();
2017 if (route == _control_out) {
2018 _control_out = shared_ptr<Route> ();
2020 /* cancel control outs for all routes */
2022 vector<string> empty;
2024 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2025 (*r)->set_control_outs (empty);
2029 update_route_solo_state ();
2031 /* writer goes out of scope, forces route list update */
2035 boost::shared_ptr<Diskstream> ds;
2037 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
2038 ds = t->diskstream();
2044 RCUWriter<DiskstreamList> dsl (diskstreams);
2045 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2050 find_current_end ();
2052 update_latency_compensation (false, false);
2055 // We need to disconnect the routes inputs and outputs
2056 route->disconnect_inputs(NULL);
2057 route->disconnect_outputs(NULL);
2059 /* get rid of it from the dead wood collection in the route list manager */
2061 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2065 /* try to cause everyone to drop their references */
2067 route->drop_references ();
2069 /* save the new state of the world */
2071 if (save_state (_current_snapshot_name)) {
2072 save_history (_current_snapshot_name);
2077 Session::route_mute_changed (void* src)
2083 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2085 if (solo_update_disabled) {
2091 boost::shared_ptr<Route> route = wpr.lock ();
2094 /* should not happen */
2095 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2099 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2101 shared_ptr<RouteList> r = routes.reader ();
2103 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2105 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2109 /* don't mess with busses */
2111 if (dynamic_cast<Track*>((*i).get()) == 0) {
2117 /* don't mess with tracks */
2119 if (dynamic_cast<Track*>((*i).get()) != 0) {
2124 if ((*i) != route &&
2125 ((*i)->mix_group () == 0 ||
2126 (*i)->mix_group () != route->mix_group () ||
2127 !route->mix_group ()->is_active())) {
2129 if ((*i)->soloed()) {
2131 /* if its already soloed, and solo latching is enabled,
2132 then leave it as it is.
2135 if (Config->get_solo_latched()) {
2142 solo_update_disabled = true;
2143 (*i)->set_solo (false, src);
2144 solo_update_disabled = false;
2148 bool something_soloed = false;
2149 bool same_thing_soloed = false;
2150 bool signal = false;
2152 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2153 if ((*i)->soloed()) {
2154 something_soloed = true;
2155 if (dynamic_cast<Track*>((*i).get())) {
2157 same_thing_soloed = true;
2162 same_thing_soloed = true;
2170 if (something_soloed != currently_soloing) {
2172 currently_soloing = something_soloed;
2175 modify_solo_mute (is_track, same_thing_soloed);
2178 SoloActive (currently_soloing);
2185 Session::update_route_solo_state ()
2188 bool is_track = false;
2189 bool signal = false;
2191 /* caller must hold RouteLock */
2193 /* this is where we actually implement solo by changing
2194 the solo mute setting of each track.
2197 shared_ptr<RouteList> r = routes.reader ();
2199 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2200 if ((*i)->soloed()) {
2202 if (dynamic_cast<Track*>((*i).get())) {
2209 if (mute != currently_soloing) {
2211 currently_soloing = mute;
2214 if (!is_track && !mute) {
2216 /* nothing is soloed */
2218 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2219 (*i)->set_solo_mute (false);
2229 modify_solo_mute (is_track, mute);
2232 SoloActive (currently_soloing);
2237 Session::modify_solo_mute (bool is_track, bool mute)
2239 shared_ptr<RouteList> r = routes.reader ();
2241 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2245 /* only alter track solo mute */
2247 if (dynamic_cast<Track*>((*i).get())) {
2248 if ((*i)->soloed()) {
2249 (*i)->set_solo_mute (!mute);
2251 (*i)->set_solo_mute (mute);
2257 /* only alter bus solo mute */
2259 if (!dynamic_cast<Track*>((*i).get())) {
2261 if ((*i)->soloed()) {
2263 (*i)->set_solo_mute (false);
2267 /* don't mute master or control outs
2268 in response to another bus solo
2271 if ((*i) != _master_out &&
2272 (*i) != _control_out) {
2273 (*i)->set_solo_mute (mute);
2284 Session::catch_up_on_solo ()
2286 /* this is called after set_state() to catch the full solo
2287 state, which can't be correctly determined on a per-route
2288 basis, but needs the global overview that only the session
2291 update_route_solo_state();
2295 Session::route_by_name (string name)
2297 shared_ptr<RouteList> r = routes.reader ();
2299 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2300 if ((*i)->name() == name) {
2305 return shared_ptr<Route> ((Route*) 0);
2309 Session::route_by_id (PBD::ID id)
2311 shared_ptr<RouteList> r = routes.reader ();
2313 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2314 if ((*i)->id() == id) {
2319 return shared_ptr<Route> ((Route*) 0);
2323 Session::route_by_remote_id (uint32_t id)
2325 shared_ptr<RouteList> r = routes.reader ();
2327 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2328 if ((*i)->remote_control_id() == id) {
2333 return shared_ptr<Route> ((Route*) 0);
2337 Session::find_current_end ()
2339 if (_state_of_the_state & Loading) {
2343 nframes_t max = get_maximum_extent ();
2345 if (max > end_location->end()) {
2346 end_location->set_end (max);
2348 DurationChanged(); /* EMIT SIGNAL */
2353 Session::get_maximum_extent () const
2358 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2360 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2361 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2362 if ((me = pl->get_maximum_extent()) > max) {
2370 boost::shared_ptr<Diskstream>
2371 Session::diskstream_by_name (string name)
2373 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2375 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2376 if ((*i)->name() == name) {
2381 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2384 boost::shared_ptr<Diskstream>
2385 Session::diskstream_by_id (const PBD::ID& id)
2387 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2389 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2390 if ((*i)->id() == id) {
2395 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2398 /* Region management */
2401 Session::new_region_name (string old)
2403 string::size_type last_period;
2405 string::size_type len = old.length() + 64;
2408 if ((last_period = old.find_last_of ('.')) == string::npos) {
2410 /* no period present - add one explicitly */
2413 last_period = old.length() - 1;
2418 number = atoi (old.substr (last_period+1).c_str());
2422 while (number < (UINT_MAX-1)) {
2424 RegionList::const_iterator i;
2429 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2432 for (i = regions.begin(); i != regions.end(); ++i) {
2433 if (i->second->name() == sbuf) {
2438 if (i == regions.end()) {
2443 if (number != (UINT_MAX-1)) {
2447 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2452 Session::region_name (string& result, string base, bool newlevel) const
2457 assert(base.find("/") == string::npos);
2461 Glib::Mutex::Lock lm (region_lock);
2463 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2471 /* XXX this is going to be slow. optimize me later */
2476 string::size_type pos;
2478 pos = base.find_last_of ('.');
2480 /* pos may be npos, but then we just use entire base */
2482 subbase = base.substr (0, pos);
2486 bool name_taken = true;
2489 Glib::Mutex::Lock lm (region_lock);
2491 for (int n = 1; n < 5000; ++n) {
2494 snprintf (buf, sizeof (buf), ".%d", n);
2499 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2500 if (i->second->name() == result) {
2513 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2521 Session::add_region (boost::shared_ptr<Region> region)
2523 boost::shared_ptr<Region> other;
2527 Glib::Mutex::Lock lm (region_lock);
2529 RegionList::iterator x;
2531 for (x = regions.begin(); x != regions.end(); ++x) {
2535 if (region->region_list_equivalent (other)) {
2540 if (x == regions.end()) {
2542 pair<RegionList::key_type,RegionList::mapped_type> entry;
2544 entry.first = region->id();
2545 entry.second = region;
2547 pair<RegionList::iterator,bool> x = regions.insert (entry);
2559 /* mark dirty because something has changed even if we didn't
2560 add the region to the region list.
2566 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2567 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2568 RegionAdded (region); /* EMIT SIGNAL */
2573 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2575 boost::shared_ptr<Region> region (weak_region.lock ());
2581 if (what_changed & Region::HiddenChanged) {
2582 /* relay hidden changes */
2583 RegionHiddenChange (region);
2588 Session::remove_region (boost::weak_ptr<Region> weak_region)
2590 RegionList::iterator i;
2591 boost::shared_ptr<Region> region (weak_region.lock ());
2597 bool removed = false;
2600 Glib::Mutex::Lock lm (region_lock);
2602 if ((i = regions.find (region->id())) != regions.end()) {
2608 /* mark dirty because something has changed even if we didn't
2609 remove the region from the region list.
2615 RegionRemoved(region); /* EMIT SIGNAL */
2619 boost::shared_ptr<Region>
2620 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2622 RegionList::iterator i;
2623 boost::shared_ptr<Region> region;
2625 Glib::Mutex::Lock lm (region_lock);
2627 for (i = regions.begin(); i != regions.end(); ++i) {
2631 if (region->whole_file()) {
2633 if (child->source_equivalent (region)) {
2639 return boost::shared_ptr<Region> ();
2643 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2645 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2646 (*i)->get_region_list_equivalent_regions (region, result);
2650 Session::destroy_region (boost::shared_ptr<Region> region)
2652 vector<boost::shared_ptr<Source> > srcs;
2655 boost::shared_ptr<AudioRegion> aregion;
2657 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2661 if (aregion->playlist()) {
2662 aregion->playlist()->destroy_region (region);
2665 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2666 srcs.push_back (aregion->source (n));
2670 region->drop_references ();
2672 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2674 if (!(*i)->used()) {
2675 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2678 (afs)->mark_for_remove ();
2681 (*i)->drop_references ();
2683 cerr << "source was not used by any playlist\n";
2691 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2693 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2694 destroy_region (*i);
2700 Session::remove_last_capture ()
2702 list<boost::shared_ptr<Region> > r;
2704 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2706 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2707 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2710 r.insert (r.end(), l.begin(), l.end());
2715 destroy_regions (r);
2720 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2726 /* Source Management */
2728 Session::add_source (boost::shared_ptr<Source> source)
2730 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2731 pair<SourceMap::iterator,bool> result;
2733 entry.first = source->id();
2734 entry.second = source;
2737 Glib::Mutex::Lock lm (source_lock);
2738 result = sources.insert (entry);
2741 if (result.second) {
2742 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2748 Session::remove_source (boost::weak_ptr<Source> src)
2750 SourceMap::iterator i;
2751 boost::shared_ptr<Source> source = src.lock();
2758 Glib::Mutex::Lock lm (source_lock);
2761 Glib::Mutex::Lock lm (source_lock);
2763 if ((i = sources.find (source->id())) != sources.end()) {
2769 if (!_state_of_the_state & InCleanup) {
2771 /* save state so we don't end up with a session file
2772 referring to non-existent sources.
2775 save_state (_current_snapshot_name);
2779 boost::shared_ptr<Source>
2780 Session::source_by_id (const PBD::ID& id)
2782 Glib::Mutex::Lock lm (source_lock);
2783 SourceMap::iterator i;
2784 boost::shared_ptr<Source> source;
2786 if ((i = sources.find (id)) != sources.end()) {
2790 /* XXX search MIDI or other searches here */
2796 Session::peak_path_from_audio_path (string audio_path) const
2801 res += PBD::basename_nosuffix (audio_path);
2808 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2811 string old_basename = PBD::basename_nosuffix (oldname);
2812 string new_legalized = legalize_for_path (newname);
2814 /* note: we know (or assume) the old path is already valid */
2818 /* destructive file sources have a name of the form:
2820 /path/to/Tnnnn-NAME(%[LR])?.wav
2822 the task here is to replace NAME with the new name.
2825 /* find last slash */
2829 string::size_type slash;
2830 string::size_type dash;
2832 if ((slash = path.find_last_of ('/')) == string::npos) {
2836 dir = path.substr (0, slash+1);
2838 /* '-' is not a legal character for the NAME part of the path */
2840 if ((dash = path.find_last_of ('-')) == string::npos) {
2844 prefix = path.substr (slash+1, dash-(slash+1));
2849 path += new_legalized;
2850 path += ".wav"; /* XXX gag me with a spoon */
2854 /* non-destructive file sources have a name of the form:
2856 /path/to/NAME-nnnnn(%[LR])?.wav
2858 the task here is to replace NAME with the new name.
2863 string::size_type slash;
2864 string::size_type dash;
2865 string::size_type postfix;
2867 /* find last slash */
2869 if ((slash = path.find_last_of ('/')) == string::npos) {
2873 dir = path.substr (0, slash+1);
2875 /* '-' is not a legal character for the NAME part of the path */
2877 if ((dash = path.find_last_of ('-')) == string::npos) {
2881 suffix = path.substr (dash+1);
2883 // Suffix is now everything after the dash. Now we need to eliminate
2884 // the nnnnn part, which is done by either finding a '%' or a '.'
2886 postfix = suffix.find_last_of ("%");
2887 if (postfix == string::npos) {
2888 postfix = suffix.find_last_of ('.');
2891 if (postfix != string::npos) {
2892 suffix = suffix.substr (postfix);
2894 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2898 const uint32_t limit = 10000;
2899 char buf[PATH_MAX+1];
2901 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2903 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2905 if (access (buf, F_OK) != 0) {
2913 error << "FATAL ERROR! Could not find a " << endl;
2922 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2926 char buf[PATH_MAX+1];
2927 const uint32_t limit = 10000;
2931 legalized = legalize_for_path (name);
2933 /* find a "version" of the file name that doesn't exist in
2934 any of the possible directories.
2937 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2939 vector<space_and_path>::iterator i;
2940 uint32_t existing = 0;
2942 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2946 spath += sound_dir (false);
2950 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2951 } else if (nchan == 2) {
2953 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2955 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2957 } else if (nchan < 26) {
2958 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2960 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2969 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2970 } else if (nchan == 2) {
2972 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2974 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2976 } else if (nchan < 26) {
2977 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2979 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2983 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2989 if (existing == 0) {
2994 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2996 throw failed_constructor();
3000 /* we now have a unique name for the file, but figure out where to
3006 spath = discover_best_sound_dir ();
3009 string::size_type pos = foo.find_last_of ('/');
3011 if (pos == string::npos) {
3014 spath += foo.substr (pos + 1);
3020 boost::shared_ptr<AudioFileSource>
3021 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3023 string spath = audio_path_from_name (ds.name(), ds.n_channels().get(DataType::AUDIO), chan, destructive);
3024 return boost::dynamic_pointer_cast<AudioFileSource> (
3025 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
3028 // FIXME: _terrible_ code duplication
3030 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
3033 string old_basename = PBD::basename_nosuffix (oldname);
3034 string new_legalized = legalize_for_path (newname);
3036 /* note: we know (or assume) the old path is already valid */
3040 /* destructive file sources have a name of the form:
3042 /path/to/Tnnnn-NAME(%[LR])?.wav
3044 the task here is to replace NAME with the new name.
3047 /* find last slash */
3051 string::size_type slash;
3052 string::size_type dash;
3054 if ((slash = path.find_last_of ('/')) == string::npos) {
3058 dir = path.substr (0, slash+1);
3060 /* '-' is not a legal character for the NAME part of the path */
3062 if ((dash = path.find_last_of ('-')) == string::npos) {
3066 prefix = path.substr (slash+1, dash-(slash+1));
3071 path += new_legalized;
3072 path += ".mid"; /* XXX gag me with a spoon */
3076 /* non-destructive file sources have a name of the form:
3078 /path/to/NAME-nnnnn(%[LR])?.wav
3080 the task here is to replace NAME with the new name.
3085 string::size_type slash;
3086 string::size_type dash;
3087 string::size_type postfix;
3089 /* find last slash */
3091 if ((slash = path.find_last_of ('/')) == string::npos) {
3095 dir = path.substr (0, slash+1);
3097 /* '-' is not a legal character for the NAME part of the path */
3099 if ((dash = path.find_last_of ('-')) == string::npos) {
3103 suffix = path.substr (dash+1);
3105 // Suffix is now everything after the dash. Now we need to eliminate
3106 // the nnnnn part, which is done by either finding a '%' or a '.'
3108 postfix = suffix.find_last_of ("%");
3109 if (postfix == string::npos) {
3110 postfix = suffix.find_last_of ('.');
3113 if (postfix != string::npos) {
3114 suffix = suffix.substr (postfix);
3116 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3120 const uint32_t limit = 10000;
3121 char buf[PATH_MAX+1];
3123 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3125 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3127 if (access (buf, F_OK) != 0) {
3135 error << "FATAL ERROR! Could not find a " << endl;
3144 Session::midi_path_from_name (string name)
3148 char buf[PATH_MAX+1];
3149 const uint32_t limit = 10000;
3153 legalized = legalize_for_path (name);
3155 /* find a "version" of the file name that doesn't exist in
3156 any of the possible directories.
3159 for (cnt = 1; cnt <= limit; ++cnt) {
3161 vector<space_and_path>::iterator i;
3162 uint32_t existing = 0;
3164 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3166 // FIXME: different directory from audio?
3167 spath = (*i).path + sound_dir_name + "/" + legalized;
3169 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3171 if (access (buf, F_OK) == 0) {
3176 if (existing == 0) {
3181 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3182 throw failed_constructor();
3186 /* we now have a unique name for the file, but figure out where to
3192 // FIXME: different directory than audio?
3193 spath = discover_best_sound_dir ();
3195 string::size_type pos = foo.find_last_of ('/');
3197 if (pos == string::npos) {
3200 spath += foo.substr (pos + 1);
3206 boost::shared_ptr<MidiSource>
3207 Session::create_midi_source_for_session (MidiDiskstream& ds)
3209 string spath = midi_path_from_name (ds.name());
3211 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
3215 /* Playlist management */
3217 boost::shared_ptr<Playlist>
3218 Session::playlist_by_name (string name)
3220 Glib::Mutex::Lock lm (playlist_lock);
3221 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3222 if ((*i)->name() == name) {
3226 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3227 if ((*i)->name() == name) {
3232 return boost::shared_ptr<Playlist>();
3236 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3238 if (playlist->hidden()) {
3243 Glib::Mutex::Lock lm (playlist_lock);
3244 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3245 playlists.insert (playlists.begin(), playlist);
3246 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3247 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3253 PlaylistAdded (playlist); /* EMIT SIGNAL */
3257 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3260 Glib::Mutex::Lock lm (playlist_lock);
3261 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3264 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3271 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3273 boost::shared_ptr<Playlist> pl(wpl.lock());
3279 PlaylistList::iterator x;
3282 /* its not supposed to be visible */
3287 Glib::Mutex::Lock lm (playlist_lock);
3291 unused_playlists.insert (pl);
3293 if ((x = playlists.find (pl)) != playlists.end()) {
3294 playlists.erase (x);
3300 playlists.insert (pl);
3302 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3303 unused_playlists.erase (x);
3310 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3312 if (_state_of_the_state & Deletion) {
3316 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3323 Glib::Mutex::Lock lm (playlist_lock);
3325 PlaylistList::iterator i;
3327 i = find (playlists.begin(), playlists.end(), playlist);
3328 if (i != playlists.end()) {
3329 playlists.erase (i);
3332 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3333 if (i != unused_playlists.end()) {
3334 unused_playlists.erase (i);
3341 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3345 Session::set_audition (boost::shared_ptr<Region> r)
3347 pending_audition_region = r;
3348 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3349 schedule_butler_transport_work ();
3353 Session::audition_playlist ()
3355 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3356 ev->region.reset ();
3361 Session::non_realtime_set_audition ()
3363 if (!pending_audition_region) {
3364 auditioner->audition_current_playlist ();
3366 auditioner->audition_region (pending_audition_region);
3367 pending_audition_region.reset ();
3369 AuditionActive (true); /* EMIT SIGNAL */
3373 Session::audition_region (boost::shared_ptr<Region> r)
3375 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3381 Session::cancel_audition ()
3383 if (auditioner->active()) {
3384 auditioner->cancel_audition ();
3385 AuditionActive (false); /* EMIT SIGNAL */
3390 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3392 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3396 Session::remove_empty_sounds ()
3398 PathScanner scanner;
3400 vector<string *>* possible_audiofiles = scanner (sound_dir(), "\\.(wav|aiff|caf|w64)$", false, true);
3402 Glib::Mutex::Lock lm (source_lock);
3404 regex_t compiled_tape_track_pattern;
3407 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3411 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3413 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3417 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3419 /* never remove files that appear to be a tape track */
3421 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3426 if (AudioFileSource::is_empty (*this, *(*i))) {
3428 unlink ((*i)->c_str());
3430 string peak_path = peak_path_from_audio_path (**i);
3431 unlink (peak_path.c_str());
3437 delete possible_audiofiles;
3441 Session::is_auditioning () const
3443 /* can be called before we have an auditioner object */
3445 return auditioner->active();
3452 Session::set_all_solo (bool yn)
3454 shared_ptr<RouteList> r = routes.reader ();
3456 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3457 if (!(*i)->hidden()) {
3458 (*i)->set_solo (yn, this);
3466 Session::set_all_mute (bool yn)
3468 shared_ptr<RouteList> r = routes.reader ();
3470 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3471 if (!(*i)->hidden()) {
3472 (*i)->set_mute (yn, this);
3480 Session::n_diskstreams () const
3484 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3486 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3487 if (!(*i)->hidden()) {
3495 Session::graph_reordered ()
3497 /* don't do this stuff if we are setting up connections
3498 from a set_state() call.
3501 if (_state_of_the_state & InitialConnecting) {
3505 /* every track/bus asked for this to be handled but it was deferred because
3506 we were connecting. do it now.
3509 request_input_change_handling ();
3513 /* force all diskstreams to update their capture offset values to
3514 reflect any changes in latencies within the graph.
3517 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3519 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3520 (*i)->set_capture_offset ();
3525 Session::record_disenable_all ()
3527 record_enable_change_all (false);
3531 Session::record_enable_all ()
3533 record_enable_change_all (true);
3537 Session::record_enable_change_all (bool yn)
3539 shared_ptr<RouteList> r = routes.reader ();
3541 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3544 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3545 at->set_record_enable (yn, this);
3549 /* since we don't keep rec-enable state, don't mark session dirty */
3553 Session::add_redirect (Redirect* redirect)
3557 PortInsert* port_insert;
3558 PluginInsert* plugin_insert;
3560 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3561 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3562 _port_inserts.insert (_port_inserts.begin(), port_insert);
3563 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3564 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3566 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3569 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3570 _sends.insert (_sends.begin(), send);
3572 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3576 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3582 Session::remove_redirect (Redirect* redirect)
3586 PortInsert* port_insert;
3587 PluginInsert* plugin_insert;
3589 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3590 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3591 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3592 if (x != _port_inserts.end()) {
3593 insert_bitset[port_insert->bit_slot()] = false;
3594 _port_inserts.erase (x);
3596 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3597 _plugin_inserts.remove (plugin_insert);
3599 fatal << string_compose (_("programming error: %1"),
3600 X_("unknown type of Insert deleted!"))
3604 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3605 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3606 if (x != _sends.end()) {
3607 send_bitset[send->bit_slot()] = false;
3611 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3619 Session::available_capture_duration ()
3621 float sample_bytes_on_disk;
3623 switch (Config->get_native_file_data_format()) {
3625 sample_bytes_on_disk = 4;
3629 sample_bytes_on_disk = 3;
3633 /* impossible, but keep some gcc versions happy */
3634 fatal << string_compose (_("programming error: %1"),
3635 X_("illegal native file data format"))
3640 double scale = 4096.0 / sample_bytes_on_disk;
3642 if (_total_free_4k_blocks * scale > (double) max_frames) {
3646 return (nframes_t) floor (_total_free_4k_blocks * scale);
3650 Session::add_connection (ARDOUR::Connection* connection)
3653 Glib::Mutex::Lock guard (connection_lock);
3654 _connections.push_back (connection);
3657 ConnectionAdded (connection); /* EMIT SIGNAL */
3663 Session::remove_connection (ARDOUR::Connection* connection)
3665 bool removed = false;
3668 Glib::Mutex::Lock guard (connection_lock);
3669 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3671 if (i != _connections.end()) {
3672 _connections.erase (i);
3678 ConnectionRemoved (connection); /* EMIT SIGNAL */
3684 ARDOUR::Connection *
3685 Session::connection_by_name (string name) const
3687 Glib::Mutex::Lock lm (connection_lock);
3689 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3690 if ((*i)->name() == name) {
3699 Session::tempo_map_changed (Change ignored)
3705 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3706 * the given count with the current block size.
3709 Session::ensure_buffers (ChanCount howmany)
3711 // FIXME: NASTY assumption (midi block size == audio block size)
3712 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3713 _send_buffers->ensure_buffers(howmany, current_block_size);
3714 _silent_buffers->ensure_buffers(howmany, current_block_size);
3716 allocate_pan_automation_buffers (current_block_size, howmany.get(DataType::AUDIO), false);
3720 Session::next_insert_id ()
3722 /* this doesn't really loop forever. just think about it */
3725 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3726 if (!insert_bitset[n]) {
3727 insert_bitset[n] = true;
3728 cerr << "Returning " << n << " as insert ID\n";
3734 /* none available, so resize and try again */
3736 insert_bitset.resize (insert_bitset.size() + 16, false);
3741 Session::next_send_id ()
3743 /* this doesn't really loop forever. just think about it */
3746 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3747 if (!send_bitset[n]) {
3748 send_bitset[n] = true;
3749 cerr << "Returning " << n << " as send ID\n";
3755 /* none available, so resize and try again */
3757 send_bitset.resize (send_bitset.size() + 16, false);
3762 Session::mark_send_id (uint32_t id)
3764 if (id >= send_bitset.size()) {
3765 send_bitset.resize (id+16, false);
3767 if (send_bitset[id]) {
3768 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3770 send_bitset[id] = true;
3774 Session::mark_insert_id (uint32_t id)
3776 if (id >= insert_bitset.size()) {
3777 insert_bitset.resize (id+16, false);
3779 if (insert_bitset[id]) {
3780 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3782 insert_bitset[id] = true;
3785 /* Named Selection management */
3788 Session::named_selection_by_name (string name)
3790 Glib::Mutex::Lock lm (named_selection_lock);
3791 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3792 if ((*i)->name == name) {
3800 Session::add_named_selection (NamedSelection* named_selection)
3803 Glib::Mutex::Lock lm (named_selection_lock);
3804 named_selections.insert (named_selections.begin(), named_selection);
3807 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3813 NamedSelectionAdded (); /* EMIT SIGNAL */
3817 Session::remove_named_selection (NamedSelection* named_selection)
3819 bool removed = false;
3822 Glib::Mutex::Lock lm (named_selection_lock);
3824 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3826 if (i != named_selections.end()) {
3828 named_selections.erase (i);
3835 NamedSelectionRemoved (); /* EMIT SIGNAL */
3840 Session::reset_native_file_format ()
3842 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3844 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3845 (*i)->reset_write_sources (false);
3850 Session::route_name_unique (string n) const
3852 shared_ptr<RouteList> r = routes.reader ();
3854 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3855 if ((*i)->name() == n) {
3864 Session::n_playlists () const
3866 Glib::Mutex::Lock lm (playlist_lock);
3867 return playlists.size();
3871 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3873 if (!force && howmany <= _npan_buffers) {
3877 if (_pan_automation_buffer) {
3879 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3880 delete [] _pan_automation_buffer[i];
3883 delete [] _pan_automation_buffer;
3886 _pan_automation_buffer = new pan_t*[howmany];
3888 for (uint32_t i = 0; i < howmany; ++i) {
3889 _pan_automation_buffer[i] = new pan_t[nframes];
3892 _npan_buffers = howmany;
3896 Session::freeze (InterThreadInfo& itt)
3898 shared_ptr<RouteList> r = routes.reader ();
3900 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3904 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3905 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3916 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3917 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3920 boost::shared_ptr<Playlist> playlist;
3921 boost::shared_ptr<AudioFileSource> fsource;
3923 char buf[PATH_MAX+1];
3925 ChanCount nchans(track.audio_diskstream()->n_channels());
3927 nframes_t this_chunk;
3931 // any bigger than this seems to cause stack overflows in called functions
3932 const nframes_t chunk_size = (128 * 1024)/4;
3934 g_atomic_int_set (&processing_prohibited, 1);
3936 /* call tree *MUST* hold route_lock */
3938 if ((playlist = track.diskstream()->playlist()) == 0) {
3942 /* external redirects will be a problem */
3944 if (track.has_external_redirects()) {
3948 dir = discover_best_sound_dir ();
3950 for (uint32_t chan_n=0; chan_n < nchans.get(DataType::AUDIO); ++chan_n) {
3952 for (x = 0; x < 99999; ++x) {
3953 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3954 if (access (buf, F_OK) != 0) {
3960 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3965 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3966 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3969 catch (failed_constructor& err) {
3970 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3974 srcs.push_back (fsource);
3977 /* XXX need to flush all redirects */
3982 /* create a set of reasonably-sized buffers */
3983 buffers.ensure_buffers(nchans, chunk_size);
3984 buffers.set_count(nchans);
3986 while (to_do && !itt.cancel) {
3988 this_chunk = min (to_do, chunk_size);
3990 if (track.export_stuff (buffers, start, this_chunk)) {
3995 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3996 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3999 if (afs->write (buffers.get_audio(n).data(this_chunk), this_chunk) != this_chunk) {
4005 start += this_chunk;
4006 to_do -= this_chunk;
4008 itt.progress = (float) (1.0 - ((double) to_do / len));
4017 xnow = localtime (&now);
4019 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4020 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4023 afs->update_header (position, *xnow, now);
4027 /* build peakfile for new source */
4029 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4030 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4032 afs->build_peaks ();
4036 /* construct a region to represent the bounced material */
4038 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
4039 region_name_from_path (srcs.front()->name(), true));
4046 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4047 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4050 afs->mark_for_remove ();
4053 (*src)->drop_references ();
4057 g_atomic_int_set (&processing_prohibited, 0);
4065 Session::get_silent_buffers (ChanCount count)
4067 assert(_silent_buffers->available() >= count);
4068 _silent_buffers->set_count(count);
4070 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4071 for (size_t i=0; i < count.get(*t); ++i) {
4072 _silent_buffers->get(*t, i).clear();
4076 return *_silent_buffers;
4080 Session::get_scratch_buffers (ChanCount count)
4082 assert(_scratch_buffers->available() >= count);
4083 _scratch_buffers->set_count(count);
4084 return *_scratch_buffers;
4088 Session::get_send_buffers (ChanCount count)
4090 assert(_send_buffers->available() >= count);
4091 _send_buffers->set_count(count);
4092 return *_send_buffers;
4096 Session::ntracks () const
4099 shared_ptr<RouteList> r = routes.reader ();
4101 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4102 if (dynamic_cast<Track*> ((*i).get())) {
4111 Session::nbusses () const
4114 shared_ptr<RouteList> r = routes.reader ();
4116 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4117 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4126 Session::add_automation_list(AutomationList *al)
4128 automation_lists[al->id()] = al;
4132 Session::compute_initial_length ()
4134 return _engine.frame_rate() * 60 * 5;