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.
25 #include <cstdio> /* sprintf(3) ... grrr */
31 #include <sigc++/bind.h>
32 #include <sigc++/retype.h>
34 #include <glibmm/thread.h>
35 #include <glibmm/miscutils.h>
37 #include <pbd/error.h>
38 #include <glibmm/thread.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/stl_delete.h>
41 #include <pbd/basename.h>
42 #include <pbd/stacktrace.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/auditioner.h>
57 #include <ardour/recent_sessions.h>
58 #include <ardour/redirect.h>
59 #include <ardour/send.h>
60 #include <ardour/insert.h>
61 #include <ardour/connection.h>
62 #include <ardour/slave.h>
63 #include <ardour/tempo.h>
64 #include <ardour/audio_track.h>
65 #include <ardour/midi_track.h>
66 #include <ardour/cycle_timer.h>
67 #include <ardour/named_selection.h>
68 #include <ardour/crossfade.h>
69 #include <ardour/playlist.h>
70 #include <ardour/click.h>
71 #include <ardour/data_type.h>
72 #include <ardour/buffer_set.h>
73 #include <ardour/source_factory.h>
74 #include <ardour/region_factory.h>
75 #include <ardour/filename_extensions.h>
76 #include <ardour/session_directory.h>
79 #include <ardour/osc.h>
85 using namespace ARDOUR;
87 using boost::shared_ptr;
90 static const int CPU_CACHE_ALIGN = 64;
92 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
95 sigc::signal<int> Session::AskAboutPendingState;
96 sigc::signal<void> Session::SendFeedback;
98 sigc::signal<void> Session::SMPTEOffsetChanged;
99 sigc::signal<void> Session::StartTimeChanged;
100 sigc::signal<void> Session::EndTimeChanged;
102 Session::Session (AudioEngine &eng,
104 string snapshot_name,
105 string* mix_template)
108 _scratch_buffers(new BufferSet()),
109 _silent_buffers(new BufferSet()),
110 _send_buffers(new BufferSet()),
111 _mmc_port (default_mmc_port),
112 _mtc_port (default_mtc_port),
113 _midi_port (default_midi_port),
114 pending_events (2048),
115 //midi_requests (128), // the size of this should match the midi request pool size
116 _send_smpte_update (false),
117 diskstreams (new DiskstreamList),
118 routes (new RouteList),
119 auditioner ((Auditioner*) 0),
123 if (!eng.connected()) {
124 throw failed_constructor();
127 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
129 n_physical_outputs = _engine.n_physical_outputs();
130 n_physical_inputs = _engine.n_physical_inputs();
132 first_stage_init (fullpath, snapshot_name);
134 initialize_start_and_end_locations(0, compute_initial_length ());
136 bool new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
139 // A mix_template must be specified if using this constructor
140 // to create a new session.
141 assert(mix_template);
143 if (!create_session_directory () ||
144 !create_session_file_from_template (*mix_template)) {
146 throw failed_constructor ();
148 // Continue construction like a normal saved session from now on.
152 if (second_stage_init (new_session)) {
154 throw failed_constructor ();
157 store_recent_sessions(_name, _path);
159 bool was_dirty = dirty();
161 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
163 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
166 DirtyChanged (); /* EMIT SIGNAL */
170 Session::Session (AudioEngine &eng,
172 string snapshot_name,
173 AutoConnectOption input_ac,
174 AutoConnectOption output_ac,
175 uint32_t control_out_channels,
176 uint32_t master_out_channels,
177 uint32_t requested_physical_in,
178 uint32_t requested_physical_out,
179 nframes_t initial_length)
182 _scratch_buffers(new BufferSet()),
183 _silent_buffers(new BufferSet()),
184 _send_buffers(new BufferSet()),
185 _mmc_port (default_mmc_port),
186 _mtc_port (default_mtc_port),
187 _midi_port (default_midi_port),
188 pending_events (2048),
189 //midi_requests (16),
190 _send_smpte_update (false),
191 diskstreams (new DiskstreamList),
192 routes (new RouteList),
196 if (!eng.connected()) {
197 throw failed_constructor();
200 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
202 n_physical_outputs = _engine.n_physical_outputs();
203 n_physical_inputs = _engine.n_physical_inputs();
205 if (n_physical_inputs) {
206 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
209 if (n_physical_outputs) {
210 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
213 first_stage_init (fullpath, snapshot_name);
215 initialize_start_and_end_locations(0, initial_length);
217 SessionDirectory sdir(fullpath);
219 if (!sdir.create () || !create_session_file ()) {
221 throw failed_constructor ();
225 /* set up Master Out and Control Out if necessary */
230 if (control_out_channels) {
231 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
232 r->set_remote_control_id (control_id++);
237 if (master_out_channels) {
238 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
239 r->set_remote_control_id (control_id);
243 /* prohibit auto-connect to master, because there isn't one */
244 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
253 Config->set_input_auto_connect (input_ac);
254 Config->set_output_auto_connect (output_ac);
256 if (second_stage_init (true)) {
258 throw failed_constructor ();
261 store_recent_sessions(_name, _path);
263 bool was_dirty = dirty ();
265 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
267 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
270 DirtyChanged (); /* EMIT SIGNAL */
282 /* if we got to here, leaving pending capture state around
286 remove_pending_capture_state ();
288 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
289 _engine.remove_session ();
291 GoingAway (); /* EMIT SIGNAL */
297 /* clear history so that no references to objects are held any more */
301 /* clear state tree so that no references to objects are held any more */
307 terminate_butler_thread ();
308 //terminate_midi_thread ();
310 if (click_data && click_data != default_click) {
311 delete [] click_data;
314 if (click_emphasis_data && click_emphasis_data != default_click_emphasis) {
315 delete [] click_emphasis_data;
320 delete _scratch_buffers;
321 delete _silent_buffers;
322 delete _send_buffers;
324 AudioDiskstream::free_working_buffers();
326 #undef TRACK_DESTRUCTION
327 #ifdef TRACK_DESTRUCTION
328 cerr << "delete named selections\n";
329 #endif /* TRACK_DESTRUCTION */
330 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
331 NamedSelectionList::iterator tmp;
340 #ifdef TRACK_DESTRUCTION
341 cerr << "delete playlists\n";
342 #endif /* TRACK_DESTRUCTION */
343 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
344 PlaylistList::iterator tmp;
349 (*i)->drop_references ();
354 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
355 PlaylistList::iterator tmp;
360 (*i)->drop_references ();
366 unused_playlists.clear ();
368 #ifdef TRACK_DESTRUCTION
369 cerr << "delete regions\n";
370 #endif /* TRACK_DESTRUCTION */
372 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
373 RegionList::iterator tmp;
378 i->second->drop_references ();
385 #ifdef TRACK_DESTRUCTION
386 cerr << "delete routes\n";
387 #endif /* TRACK_DESTRUCTION */
389 RCUWriter<RouteList> writer (routes);
390 boost::shared_ptr<RouteList> r = writer.get_copy ();
391 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
392 (*i)->drop_references ();
395 /* writer goes out of scope and updates master */
400 #ifdef TRACK_DESTRUCTION
401 cerr << "delete diskstreams\n";
402 #endif /* TRACK_DESTRUCTION */
404 RCUWriter<DiskstreamList> dwriter (diskstreams);
405 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
406 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
407 (*i)->drop_references ();
411 diskstreams.flush ();
413 #ifdef TRACK_DESTRUCTION
414 cerr << "delete audio sources\n";
415 #endif /* TRACK_DESTRUCTION */
416 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
417 SourceMap::iterator tmp;
422 i->second->drop_references ();
429 #ifdef TRACK_DESTRUCTION
430 cerr << "delete mix groups\n";
431 #endif /* TRACK_DESTRUCTION */
432 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
433 list<RouteGroup*>::iterator tmp;
443 #ifdef TRACK_DESTRUCTION
444 cerr << "delete edit groups\n";
445 #endif /* TRACK_DESTRUCTION */
446 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
447 list<RouteGroup*>::iterator tmp;
457 #ifdef TRACK_DESTRUCTION
458 cerr << "delete connections\n";
459 #endif /* TRACK_DESTRUCTION */
460 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ) {
461 ConnectionList::iterator tmp;
471 if (butler_mixdown_buffer) {
472 delete [] butler_mixdown_buffer;
475 if (butler_gain_buffer) {
476 delete [] butler_gain_buffer;
479 Crossfade::set_buffer_size (0);
487 Session::set_worst_io_latencies ()
489 _worst_output_latency = 0;
490 _worst_input_latency = 0;
492 if (!_engine.connected()) {
496 boost::shared_ptr<RouteList> r = routes.reader ();
498 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
499 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
500 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
505 Session::when_engine_running ()
507 string first_physical_output;
509 /* we don't want to run execute this again */
511 set_block_size (_engine.frames_per_cycle());
512 set_frame_rate (_engine.frame_rate());
514 Config->map_parameters (mem_fun (*this, &Session::config_changed));
516 /* every time we reconnect, recompute worst case output latencies */
518 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
520 if (synced_to_jack()) {
521 _engine.transport_stop ();
524 if (Config->get_jack_time_master()) {
525 _engine.transport_locate (_transport_frame);
533 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
535 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
537 /* existing state for Click */
539 if (_click_io->set_state (*child->children().front()) == 0) {
541 _clicking = Config->get_clicking ();
545 error << _("could not setup Click I/O") << endmsg;
551 /* default state for Click */
553 first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0);
555 if (first_physical_output.length()) {
556 if (_click_io->add_output_port (first_physical_output, this)) {
557 // relax, even though its an error
559 _clicking = Config->get_clicking ();
565 catch (failed_constructor& err) {
566 error << _("cannot setup Click I/O") << endmsg;
569 set_worst_io_latencies ();
572 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
575 /* Create a set of Connection objects that map
576 to the physical outputs currently available
581 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
583 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
585 Connection* c = new OutputConnection (buf, true);
588 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
593 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
595 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
597 Connection* c = new InputConnection (buf, true);
600 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
607 for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
609 snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
611 Connection* c = new OutputConnection (buf, true);
615 c->add_connection (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
616 c->add_connection (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1));
621 for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
623 snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
625 Connection* c = new InputConnection (buf, true);
629 c->add_connection (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
630 c->add_connection (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1));
639 /* create master/control ports */
644 /* force the master to ignore any later call to this */
646 if (_master_out->pending_state_node) {
647 _master_out->ports_became_legal();
650 /* no panner resets till we are through */
652 _master_out->defer_pan_reset ();
654 while (_master_out->n_inputs().n_audio()
655 < _master_out->input_maximum().n_audio()) {
656 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
657 error << _("cannot setup master inputs")
663 while (_master_out->n_outputs().n_audio()
664 < _master_out->output_maximum().n_audio()) {
665 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
666 error << _("cannot setup master outputs")
673 _master_out->allow_pan_reset ();
677 Connection* c = new OutputConnection (_("Master Out"), true);
679 for (uint32_t n = 0; n < _master_out->n_inputs ().get_total(); ++n) {
681 c->add_connection ((int) n, _master_out->input(n)->name());
688 /* catch up on send+insert cnts */
692 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
695 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
696 if (id > insert_cnt) {
704 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
707 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
715 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
717 /* hook us up to the engine */
719 _engine.set_session (this);
724 osc->set_session (*this);
727 _state_of_the_state = Clean;
729 DirtyChanged (); /* EMIT SIGNAL */
733 Session::hookup_io ()
735 /* stop graph reordering notifications from
736 causing resorts, etc.
739 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
741 if (auditioner == 0) {
743 /* we delay creating the auditioner till now because
744 it makes its own connections to ports.
745 the engine has to be running for this to work.
749 auditioner.reset (new Auditioner (*this));
752 catch (failed_constructor& err) {
753 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
757 /* Tell all IO objects to create their ports */
763 vector<string> cports;
765 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
766 if (_control_out->add_input_port ("", this)) {
767 error << _("cannot setup control inputs")
773 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
774 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
775 error << _("cannot set up master outputs")
783 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
785 for (n = 0; n < ni; ++n) {
786 cports.push_back (_control_out->input(n)->name());
789 boost::shared_ptr<RouteList> r = routes.reader ();
791 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
792 (*x)->set_control_outs (cports);
796 /* Tell all IO objects to connect themselves together */
798 IO::enable_connecting ();
800 /* Now reset all panners */
802 IO::reset_panners ();
804 /* Anyone who cares about input state, wake up and do something */
806 IOConnectionsComplete (); /* EMIT SIGNAL */
808 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
810 /* now handle the whole enchilada as if it was one
816 /* update mixer solo state */
822 Session::playlist_length_changed ()
824 /* we can't just increase end_location->end() if pl->get_maximum_extent()
825 if larger. if the playlist used to be the longest playlist,
826 and its now shorter, we have to decrease end_location->end(). hence,
827 we have to iterate over all diskstreams and check the
828 playlists currently in use.
834 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
836 boost::shared_ptr<Playlist> playlist;
838 if ((playlist = dstream->playlist()) != 0) {
839 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
842 /* see comment in playlist_length_changed () */
847 Session::record_enabling_legal () const
849 /* this used to be in here, but survey says.... we don't need to restrict it */
850 // if (record_status() == Recording) {
854 if (Config->get_all_safe()) {
861 Session::reset_input_monitor_state ()
863 if (transport_rolling()) {
865 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
867 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
868 if ((*i)->record_enabled ()) {
869 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
870 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
874 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
876 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
877 if ((*i)->record_enabled ()) {
878 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
879 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
886 Session::auto_punch_start_changed (Location* location)
888 replace_event (Event::PunchIn, location->start());
890 if (get_record_enabled() && Config->get_punch_in()) {
891 /* capture start has been changed, so save new pending state */
892 save_state ("", true);
897 Session::auto_punch_end_changed (Location* location)
899 nframes_t when_to_stop = location->end();
900 // when_to_stop += _worst_output_latency + _worst_input_latency;
901 replace_event (Event::PunchOut, when_to_stop);
905 Session::auto_punch_changed (Location* location)
907 nframes_t when_to_stop = location->end();
909 replace_event (Event::PunchIn, location->start());
910 //when_to_stop += _worst_output_latency + _worst_input_latency;
911 replace_event (Event::PunchOut, when_to_stop);
915 Session::auto_loop_changed (Location* location)
917 replace_event (Event::AutoLoop, location->end(), location->start());
919 if (transport_rolling() && play_loop) {
921 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
923 if (_transport_frame > location->end()) {
924 // relocate to beginning of loop
925 clear_events (Event::LocateRoll);
927 request_locate (location->start(), true);
930 else if (Config->get_seamless_loop() && !loop_changing) {
932 // schedule a locate-roll to refill the diskstreams at the
934 loop_changing = true;
936 if (location->end() > last_loopend) {
937 clear_events (Event::LocateRoll);
938 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
945 last_loopend = location->end();
950 Session::set_auto_punch_location (Location* location)
954 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
955 auto_punch_start_changed_connection.disconnect();
956 auto_punch_end_changed_connection.disconnect();
957 auto_punch_changed_connection.disconnect();
958 existing->set_auto_punch (false, this);
959 remove_event (existing->start(), Event::PunchIn);
960 clear_events (Event::PunchOut);
961 auto_punch_location_changed (0);
970 if (location->end() <= location->start()) {
971 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
975 auto_punch_start_changed_connection.disconnect();
976 auto_punch_end_changed_connection.disconnect();
977 auto_punch_changed_connection.disconnect();
979 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
980 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
981 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
983 location->set_auto_punch (true, this);
984 auto_punch_location_changed (location);
988 Session::set_auto_loop_location (Location* location)
992 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
993 auto_loop_start_changed_connection.disconnect();
994 auto_loop_end_changed_connection.disconnect();
995 auto_loop_changed_connection.disconnect();
996 existing->set_auto_loop (false, this);
997 remove_event (existing->end(), Event::AutoLoop);
998 auto_loop_location_changed (0);
1003 if (location == 0) {
1007 if (location->end() <= location->start()) {
1008 error << _("Session: you can't use a mark for auto loop") << endmsg;
1012 last_loopend = location->end();
1014 auto_loop_start_changed_connection.disconnect();
1015 auto_loop_end_changed_connection.disconnect();
1016 auto_loop_changed_connection.disconnect();
1018 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1019 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1020 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1022 location->set_auto_loop (true, this);
1023 auto_loop_location_changed (location);
1027 Session::locations_added (Location* ignored)
1033 Session::locations_changed ()
1035 _locations.apply (*this, &Session::handle_locations_changed);
1039 Session::handle_locations_changed (Locations::LocationList& locations)
1041 Locations::LocationList::iterator i;
1043 bool set_loop = false;
1044 bool set_punch = false;
1046 for (i = locations.begin(); i != locations.end(); ++i) {
1050 if (location->is_auto_punch()) {
1051 set_auto_punch_location (location);
1054 if (location->is_auto_loop()) {
1055 set_auto_loop_location (location);
1062 set_auto_loop_location (0);
1065 set_auto_punch_location (0);
1072 Session::enable_record ()
1074 /* XXX really atomic compare+swap here */
1075 if (g_atomic_int_get (&_record_status) != Recording) {
1076 g_atomic_int_set (&_record_status, Recording);
1077 _last_record_location = _transport_frame;
1078 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1080 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1081 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1082 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1083 if ((*i)->record_enabled ()) {
1084 (*i)->monitor_input (true);
1089 RecordStateChanged ();
1094 Session::disable_record (bool rt_context, bool force)
1098 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1100 if (!Config->get_latched_record_enable () || force) {
1101 g_atomic_int_set (&_record_status, Disabled);
1103 if (rs == Recording) {
1104 g_atomic_int_set (&_record_status, Enabled);
1108 // FIXME: timestamp correct? [DR]
1109 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1110 // does this /need/ to be sent in all cases?
1112 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1114 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1115 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1117 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1118 if ((*i)->record_enabled ()) {
1119 (*i)->monitor_input (false);
1124 RecordStateChanged (); /* emit signal */
1127 remove_pending_capture_state ();
1133 Session::step_back_from_record ()
1135 g_atomic_int_set (&_record_status, Enabled);
1137 if (Config->get_monitoring_model() == HardwareMonitoring) {
1138 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1140 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1141 if (Config->get_auto_input() && (*i)->record_enabled ()) {
1142 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1143 (*i)->monitor_input (false);
1150 Session::maybe_enable_record ()
1152 g_atomic_int_set (&_record_status, Enabled);
1154 /* this function is currently called from somewhere other than an RT thread.
1155 this save_state() call therefore doesn't impact anything.
1158 save_state ("", true);
1160 if (_transport_speed) {
1161 if (!Config->get_punch_in()) {
1165 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1166 RecordStateChanged (); /* EMIT SIGNAL */
1173 Session::audible_frame () const
1179 /* the first of these two possible settings for "offset"
1180 mean that the audible frame is stationary until
1181 audio emerges from the latency compensation
1184 the second means that the audible frame is stationary
1185 until audio would emerge from a physical port
1186 in the absence of any plugin latency compensation
1189 offset = _worst_output_latency;
1191 if (offset > current_block_size) {
1192 offset -= current_block_size;
1194 /* XXX is this correct? if we have no external
1195 physical connections and everything is internal
1196 then surely this is zero? still, how
1197 likely is that anyway?
1199 offset = current_block_size;
1202 if (synced_to_jack()) {
1203 tf = _engine.transport_frame();
1205 tf = _transport_frame;
1208 if (_transport_speed == 0) {
1218 if (!non_realtime_work_pending()) {
1222 /* take latency into account */
1231 Session::set_frame_rate (nframes_t frames_per_second)
1233 /** \fn void Session::set_frame_size(nframes_t)
1234 the AudioEngine object that calls this guarantees
1235 that it will not be called while we are also in
1236 ::process(). Its fine to do things that block
1240 _base_frame_rate = frames_per_second;
1244 Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
1246 // XXX we need some equivalent to this, somehow
1247 // SndFileSource::setup_standard_crossfades (frames_per_second);
1251 /* XXX need to reset/reinstantiate all LADSPA plugins */
1255 Session::set_block_size (nframes_t nframes)
1257 /* the AudioEngine guarantees
1258 that it will not be called while we are also in
1259 ::process(). It is therefore fine to do things that block
1265 current_block_size = nframes;
1267 ensure_buffers(_scratch_buffers->available());
1269 if (_gain_automation_buffer) {
1270 delete [] _gain_automation_buffer;
1272 _gain_automation_buffer = new gain_t[nframes];
1274 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1276 boost::shared_ptr<RouteList> r = routes.reader ();
1278 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1279 (*i)->set_block_size (nframes);
1282 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1283 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1284 (*i)->set_block_size (nframes);
1287 set_worst_io_latencies ();
1292 Session::set_default_fade (float steepness, float fade_msecs)
1295 nframes_t fade_frames;
1297 /* Don't allow fade of less 1 frame */
1299 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1306 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1310 default_fade_msecs = fade_msecs;
1311 default_fade_steepness = steepness;
1314 // jlc, WTF is this!
1315 Glib::RWLock::ReaderLock lm (route_lock);
1316 AudioRegion::set_default_fade (steepness, fade_frames);
1321 /* XXX have to do this at some point */
1322 /* foreach region using default fade, reset, then
1323 refill_all_diskstream_buffers ();
1328 struct RouteSorter {
1329 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1330 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1332 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1335 if (r1->fed_by.empty()) {
1336 if (r2->fed_by.empty()) {
1337 /* no ardour-based connections inbound to either route. just use signal order */
1338 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1340 /* r2 has connections, r1 does not; run r1 early */
1344 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1351 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1353 shared_ptr<Route> r2;
1355 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1356 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1360 /* make a copy of the existing list of routes that feed r1 */
1362 set<shared_ptr<Route> > existing = r1->fed_by;
1364 /* for each route that feeds r1, recurse, marking it as feeding
1368 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1371 /* r2 is a route that feeds r1 which somehow feeds base. mark
1372 base as being fed by r2
1375 rbase->fed_by.insert (r2);
1379 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1383 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1387 /* now recurse, so that we can mark base as being fed by
1388 all routes that feed r2
1391 trace_terminal (r2, rbase);
1398 Session::resort_routes ()
1400 /* don't do anything here with signals emitted
1401 by Routes while we are being destroyed.
1404 if (_state_of_the_state & Deletion) {
1411 RCUWriter<RouteList> writer (routes);
1412 shared_ptr<RouteList> r = writer.get_copy ();
1413 resort_routes_using (r);
1414 /* writer goes out of scope and forces update */
1419 Session::resort_routes_using (shared_ptr<RouteList> r)
1421 RouteList::iterator i, j;
1423 for (i = r->begin(); i != r->end(); ++i) {
1425 (*i)->fed_by.clear ();
1427 for (j = r->begin(); j != r->end(); ++j) {
1429 /* although routes can feed themselves, it will
1430 cause an endless recursive descent if we
1431 detect it. so don't bother checking for
1439 if ((*j)->feeds (*i)) {
1440 (*i)->fed_by.insert (*j);
1445 for (i = r->begin(); i != r->end(); ++i) {
1446 trace_terminal (*i, *i);
1453 cerr << "finished route resort\n";
1455 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1456 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1463 list<boost::shared_ptr<MidiTrack> >
1464 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1466 char track_name[32];
1467 uint32_t track_id = 0;
1469 uint32_t channels_used = 0;
1471 RouteList new_routes;
1472 list<boost::shared_ptr<MidiTrack> > ret;
1474 /* count existing midi tracks */
1477 shared_ptr<RouteList> r = routes.reader ();
1479 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1480 if (dynamic_cast<MidiTrack*>((*i).get()) != 0) {
1481 if (!(*i)->hidden()) {
1483 channels_used += (*i)->n_inputs().n_midi();
1491 /* check for duplicate route names, since we might have pre-existing
1492 routes with this name (e.g. create Midi1, Midi2, delete Midi1,
1493 save, close,restart,add new route - first named route is now
1501 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1503 if (route_by_name (track_name) == 0) {
1507 } while (track_id < (UINT_MAX-1));
1510 shared_ptr<MidiTrack> track (new MidiTrack (*this, track_name, Route::Flag (0), mode));
1512 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::MIDI, 1), false, this)) {
1513 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1516 channels_used += track->n_inputs ().n_midi();
1518 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1519 track->set_remote_control_id (ntracks());
1521 new_routes.push_back (track);
1522 ret.push_back (track);
1525 catch (failed_constructor &err) {
1526 error << _("Session: could not create new midi track.") << endmsg;
1527 // XXX should we delete the tracks already created?
1535 if (!new_routes.empty()) {
1536 add_routes (new_routes, false);
1537 save_state (_current_snapshot_name);
1543 list<boost::shared_ptr<AudioTrack> >
1544 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1546 char track_name[32];
1547 uint32_t track_id = 0;
1549 uint32_t channels_used = 0;
1551 RouteList new_routes;
1552 list<boost::shared_ptr<AudioTrack> > ret;
1553 uint32_t control_id;
1555 /* count existing audio tracks */
1558 shared_ptr<RouteList> r = routes.reader ();
1560 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1561 if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
1562 if (!(*i)->hidden()) {
1564 channels_used += (*i)->n_inputs().n_audio();
1570 vector<string> physinputs;
1571 vector<string> physoutputs;
1572 uint32_t nphysical_in;
1573 uint32_t nphysical_out;
1575 _engine.get_physical_outputs (physoutputs);
1576 _engine.get_physical_inputs (physinputs);
1577 control_id = ntracks() + nbusses() + 1;
1581 /* check for duplicate route names, since we might have pre-existing
1582 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1583 save, close,restart,add new route - first named route is now
1591 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1593 if (route_by_name (track_name) == 0) {
1597 } while (track_id < (UINT_MAX-1));
1599 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1600 nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size());
1605 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1606 nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size());
1611 shared_ptr<AudioTrack> track;
1614 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1616 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1617 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1618 input_channels, output_channels)
1624 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1628 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1629 port = physinputs[(channels_used+x)%nphysical_in];
1632 if (port.length() && track->connect_input (track->input (x), port, this)) {
1638 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1642 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1643 port = physoutputs[(channels_used+x)%nphysical_out];
1644 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1646 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1650 if (port.length() && track->connect_output (track->output (x), port, this)) {
1655 channels_used += track->n_inputs ().n_audio();
1657 track->audio_diskstream()->non_realtime_input_change();
1659 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1660 track->set_remote_control_id (control_id);
1663 new_routes.push_back (track);
1664 ret.push_back (track);
1667 catch (failed_constructor &err) {
1668 error << _("Session: could not create new audio track.") << endmsg;
1671 /* we need to get rid of this, since the track failed to be created */
1672 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1675 RCUWriter<DiskstreamList> writer (diskstreams);
1676 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1677 ds->remove (track->audio_diskstream());
1684 catch (AudioEngine::PortRegistrationFailure& pfe) {
1686 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1689 /* we need to get rid of this, since the track failed to be created */
1690 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1693 RCUWriter<DiskstreamList> writer (diskstreams);
1694 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1695 ds->remove (track->audio_diskstream());
1706 if (!new_routes.empty()) {
1707 add_routes (new_routes, false);
1708 save_state (_current_snapshot_name);
1715 Session::set_remote_control_ids ()
1717 RemoteModel m = Config->get_remote_model();
1719 shared_ptr<RouteList> r = routes.reader ();
1721 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1722 if ( MixerOrdered == m) {
1723 long order = (*i)->order_key(N_("signal"));
1724 (*i)->set_remote_control_id( order+1 );
1725 } else if ( EditorOrdered == m) {
1726 long order = (*i)->order_key(N_("editor"));
1727 (*i)->set_remote_control_id( order+1 );
1728 } else if ( UserOrdered == m) {
1729 //do nothing ... only changes to remote id's are initiated by user
1736 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1739 uint32_t bus_id = 1;
1743 uint32_t control_id;
1745 /* count existing audio busses */
1748 shared_ptr<RouteList> r = routes.reader ();
1750 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1751 if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
1752 if (!(*i)->hidden() && (*i)->name() != _("master")) {
1759 vector<string> physinputs;
1760 vector<string> physoutputs;
1762 _engine.get_physical_outputs (physoutputs);
1763 _engine.get_physical_inputs (physinputs);
1764 control_id = ntracks() + nbusses() + 1;
1769 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1773 if (route_by_name (bus_name) == 0) {
1777 } while (bus_id < (UINT_MAX-1));
1780 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1782 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1783 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1784 input_channels, output_channels)
1789 for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) {
1793 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1794 port = physinputs[((n+x)%n_physical_inputs)];
1797 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1802 for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) {
1806 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1807 port = physoutputs[((n+x)%n_physical_outputs)];
1808 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1810 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1814 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1819 bus->set_remote_control_id (control_id);
1822 ret.push_back (bus);
1826 catch (failed_constructor &err) {
1827 error << _("Session: could not create new audio route.") << endmsg;
1831 catch (AudioEngine::PortRegistrationFailure& pfe) {
1832 error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg;
1842 add_routes (ret, false);
1843 save_state (_current_snapshot_name);
1851 Session::add_routes (RouteList& new_routes, bool save)
1854 RCUWriter<RouteList> writer (routes);
1855 shared_ptr<RouteList> r = writer.get_copy ();
1856 r->insert (r->end(), new_routes.begin(), new_routes.end());
1857 resort_routes_using (r);
1860 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1862 boost::weak_ptr<Route> wpr (*x);
1864 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
1865 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
1866 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
1867 (*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
1869 if ((*x)->master()) {
1873 if ((*x)->control()) {
1874 _control_out = (*x);
1878 if (_control_out && IO::connecting_legal) {
1880 vector<string> cports;
1881 uint32_t ni = _control_out->n_inputs().n_audio();
1883 for (uint32_t n = 0; n < ni; ++n) {
1884 cports.push_back (_control_out->input(n)->name());
1887 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
1888 (*x)->set_control_outs (cports);
1895 save_state (_current_snapshot_name);
1898 RouteAdded (new_routes); /* EMIT SIGNAL */
1902 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
1904 /* need to do this in case we're rolling at the time, to prevent false underruns */
1905 dstream->do_refill_with_alloc ();
1907 dstream->set_block_size (current_block_size);
1910 RCUWriter<DiskstreamList> writer (diskstreams);
1911 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1912 ds->push_back (dstream);
1913 /* writer goes out of scope, copies ds back to main */
1916 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
1917 /* this will connect to future changes, and check the current length */
1918 diskstream_playlist_changed (dstream);
1920 dstream->prepare ();
1925 Session::remove_route (shared_ptr<Route> route)
1928 RCUWriter<RouteList> writer (routes);
1929 shared_ptr<RouteList> rs = writer.get_copy ();
1933 /* deleting the master out seems like a dumb
1934 idea, but its more of a UI policy issue
1938 if (route == _master_out) {
1939 _master_out = shared_ptr<Route> ();
1942 if (route == _control_out) {
1943 _control_out = shared_ptr<Route> ();
1945 /* cancel control outs for all routes */
1947 vector<string> empty;
1949 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
1950 (*r)->set_control_outs (empty);
1954 update_route_solo_state ();
1956 /* writer goes out of scope, forces route list update */
1960 boost::shared_ptr<Diskstream> ds;
1962 if ((t = dynamic_cast<Track*>(route.get())) != 0) {
1963 ds = t->diskstream();
1969 RCUWriter<DiskstreamList> dsl (diskstreams);
1970 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
1975 find_current_end ();
1977 update_latency_compensation (false, false);
1980 // We need to disconnect the routes inputs and outputs
1981 route->disconnect_inputs(NULL);
1982 route->disconnect_outputs(NULL);
1984 /* get rid of it from the dead wood collection in the route list manager */
1986 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
1990 /* try to cause everyone to drop their references */
1992 route->drop_references ();
1994 /* save the new state of the world */
1996 if (save_state (_current_snapshot_name)) {
1997 save_history (_current_snapshot_name);
2002 Session::route_mute_changed (void* src)
2008 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2010 if (solo_update_disabled) {
2016 boost::shared_ptr<Route> route = wpr.lock ();
2019 /* should not happen */
2020 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2024 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2026 shared_ptr<RouteList> r = routes.reader ();
2028 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2030 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2034 /* don't mess with busses */
2036 if (dynamic_cast<Track*>((*i).get()) == 0) {
2042 /* don't mess with tracks */
2044 if (dynamic_cast<Track*>((*i).get()) != 0) {
2049 if ((*i) != route &&
2050 ((*i)->mix_group () == 0 ||
2051 (*i)->mix_group () != route->mix_group () ||
2052 !route->mix_group ()->is_active())) {
2054 if ((*i)->soloed()) {
2056 /* if its already soloed, and solo latching is enabled,
2057 then leave it as it is.
2060 if (Config->get_solo_latched()) {
2067 solo_update_disabled = true;
2068 (*i)->set_solo (false, src);
2069 solo_update_disabled = false;
2073 bool something_soloed = false;
2074 bool same_thing_soloed = false;
2075 bool signal = false;
2077 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2078 if ((*i)->soloed()) {
2079 something_soloed = true;
2080 if (dynamic_cast<Track*>((*i).get())) {
2082 same_thing_soloed = true;
2087 same_thing_soloed = true;
2095 if (something_soloed != currently_soloing) {
2097 currently_soloing = something_soloed;
2100 modify_solo_mute (is_track, same_thing_soloed);
2103 SoloActive (currently_soloing); /* EMIT SIGNAL */
2106 SoloChanged (); /* EMIT SIGNAL */
2112 Session::update_route_solo_state ()
2115 bool is_track = false;
2116 bool signal = false;
2118 /* caller must hold RouteLock */
2120 /* this is where we actually implement solo by changing
2121 the solo mute setting of each track.
2124 shared_ptr<RouteList> r = routes.reader ();
2126 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2127 if ((*i)->soloed()) {
2129 if (dynamic_cast<Track*>((*i).get())) {
2136 if (mute != currently_soloing) {
2138 currently_soloing = mute;
2141 if (!is_track && !mute) {
2143 /* nothing is soloed */
2145 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2146 (*i)->set_solo_mute (false);
2156 modify_solo_mute (is_track, mute);
2159 SoloActive (currently_soloing);
2164 Session::modify_solo_mute (bool is_track, bool mute)
2166 shared_ptr<RouteList> r = routes.reader ();
2168 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2172 /* only alter track solo mute */
2174 if (dynamic_cast<Track*>((*i).get())) {
2175 if ((*i)->soloed()) {
2176 (*i)->set_solo_mute (!mute);
2178 (*i)->set_solo_mute (mute);
2184 /* only alter bus solo mute */
2186 if (!dynamic_cast<Track*>((*i).get())) {
2188 if ((*i)->soloed()) {
2190 (*i)->set_solo_mute (false);
2194 /* don't mute master or control outs
2195 in response to another bus solo
2198 if ((*i) != _master_out &&
2199 (*i) != _control_out) {
2200 (*i)->set_solo_mute (mute);
2211 Session::catch_up_on_solo ()
2213 /* this is called after set_state() to catch the full solo
2214 state, which can't be correctly determined on a per-route
2215 basis, but needs the global overview that only the session
2218 update_route_solo_state();
2222 Session::route_by_name (string name)
2224 shared_ptr<RouteList> r = routes.reader ();
2226 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2227 if ((*i)->name() == name) {
2232 return shared_ptr<Route> ((Route*) 0);
2236 Session::route_by_id (PBD::ID id)
2238 shared_ptr<RouteList> r = routes.reader ();
2240 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2241 if ((*i)->id() == id) {
2246 return shared_ptr<Route> ((Route*) 0);
2250 Session::route_by_remote_id (uint32_t id)
2252 shared_ptr<RouteList> r = routes.reader ();
2254 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2255 if ((*i)->remote_control_id() == id) {
2260 return shared_ptr<Route> ((Route*) 0);
2264 Session::find_current_end ()
2266 if (_state_of_the_state & Loading) {
2270 nframes_t max = get_maximum_extent ();
2272 if (max > end_location->end()) {
2273 end_location->set_end (max);
2275 DurationChanged(); /* EMIT SIGNAL */
2280 Session::get_maximum_extent () const
2285 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2287 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2288 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2289 if ((me = pl->get_maximum_extent()) > max) {
2297 boost::shared_ptr<Diskstream>
2298 Session::diskstream_by_name (string name)
2300 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2302 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2303 if ((*i)->name() == name) {
2308 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2311 boost::shared_ptr<Diskstream>
2312 Session::diskstream_by_id (const PBD::ID& id)
2314 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2316 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2317 if ((*i)->id() == id) {
2322 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2325 /* Region management */
2328 Session::new_region_name (string old)
2330 string::size_type last_period;
2332 string::size_type len = old.length() + 64;
2335 if ((last_period = old.find_last_of ('.')) == string::npos) {
2337 /* no period present - add one explicitly */
2340 last_period = old.length() - 1;
2345 number = atoi (old.substr (last_period+1).c_str());
2349 while (number < (UINT_MAX-1)) {
2351 RegionList::const_iterator i;
2356 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2359 for (i = regions.begin(); i != regions.end(); ++i) {
2360 if (i->second->name() == sbuf) {
2365 if (i == regions.end()) {
2370 if (number != (UINT_MAX-1)) {
2374 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2379 Session::region_name (string& result, string base, bool newlevel) const
2384 assert(base.find("/") == string::npos);
2388 Glib::Mutex::Lock lm (region_lock);
2390 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2398 /* XXX this is going to be slow. optimize me later */
2403 string::size_type pos;
2405 pos = base.find_last_of ('.');
2407 /* pos may be npos, but then we just use entire base */
2409 subbase = base.substr (0, pos);
2413 bool name_taken = true;
2416 Glib::Mutex::Lock lm (region_lock);
2418 for (int n = 1; n < 5000; ++n) {
2421 snprintf (buf, sizeof (buf), ".%d", n);
2426 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2427 if (i->second->name() == result) {
2440 fatal << string_compose(_("too many regions with names like %1"), base) << endmsg;
2448 Session::add_region (boost::shared_ptr<Region> region)
2450 boost::shared_ptr<Region> other;
2454 Glib::Mutex::Lock lm (region_lock);
2456 RegionList::iterator x;
2458 for (x = regions.begin(); x != regions.end(); ++x) {
2462 if (region->region_list_equivalent (other)) {
2467 if (x == regions.end()) {
2469 pair<RegionList::key_type,RegionList::mapped_type> entry;
2471 entry.first = region->id();
2472 entry.second = region;
2474 pair<RegionList::iterator,bool> x = regions.insert (entry);
2486 /* mark dirty because something has changed even if we didn't
2487 add the region to the region list.
2493 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2494 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2495 RegionAdded (region); /* EMIT SIGNAL */
2500 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2502 boost::shared_ptr<Region> region (weak_region.lock ());
2508 if (what_changed & Region::HiddenChanged) {
2509 /* relay hidden changes */
2510 RegionHiddenChange (region);
2515 Session::remove_region (boost::weak_ptr<Region> weak_region)
2517 RegionList::iterator i;
2518 boost::shared_ptr<Region> region (weak_region.lock ());
2524 bool removed = false;
2527 Glib::Mutex::Lock lm (region_lock);
2529 if ((i = regions.find (region->id())) != regions.end()) {
2535 /* mark dirty because something has changed even if we didn't
2536 remove the region from the region list.
2542 RegionRemoved(region); /* EMIT SIGNAL */
2546 boost::shared_ptr<Region>
2547 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2549 RegionList::iterator i;
2550 boost::shared_ptr<Region> region;
2552 Glib::Mutex::Lock lm (region_lock);
2554 for (i = regions.begin(); i != regions.end(); ++i) {
2558 if (region->whole_file()) {
2560 if (child->source_equivalent (region)) {
2566 return boost::shared_ptr<Region> ();
2570 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2572 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2573 (*i)->get_region_list_equivalent_regions (region, result);
2577 Session::destroy_region (boost::shared_ptr<Region> region)
2579 vector<boost::shared_ptr<Source> > srcs;
2582 boost::shared_ptr<AudioRegion> aregion;
2584 if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
2588 if (aregion->playlist()) {
2589 aregion->playlist()->destroy_region (region);
2592 for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
2593 srcs.push_back (aregion->source (n));
2597 region->drop_references ();
2599 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2601 if (!(*i)->used()) {
2602 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
2605 (afs)->mark_for_remove ();
2608 (*i)->drop_references ();
2610 cerr << "source was not used by any playlist\n";
2618 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2620 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2621 destroy_region (*i);
2627 Session::remove_last_capture ()
2629 list<boost::shared_ptr<Region> > r;
2631 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2633 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2634 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2637 r.insert (r.end(), l.begin(), l.end());
2642 destroy_regions (r);
2644 save_state (_current_snapshot_name);
2650 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2656 /* Source Management */
2658 Session::add_source (boost::shared_ptr<Source> source)
2660 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2661 pair<SourceMap::iterator,bool> result;
2663 entry.first = source->id();
2664 entry.second = source;
2667 Glib::Mutex::Lock lm (source_lock);
2668 result = sources.insert (entry);
2671 if (result.second) {
2672 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2678 Session::remove_source (boost::weak_ptr<Source> src)
2680 SourceMap::iterator i;
2681 boost::shared_ptr<Source> source = src.lock();
2688 Glib::Mutex::Lock lm (source_lock);
2691 Glib::Mutex::Lock lm (source_lock);
2693 if ((i = sources.find (source->id())) != sources.end()) {
2699 if (!_state_of_the_state & InCleanup) {
2701 /* save state so we don't end up with a session file
2702 referring to non-existent sources.
2705 save_state (_current_snapshot_name);
2709 boost::shared_ptr<Source>
2710 Session::source_by_id (const PBD::ID& id)
2712 Glib::Mutex::Lock lm (source_lock);
2713 SourceMap::iterator i;
2714 boost::shared_ptr<Source> source;
2716 if ((i = sources.find (id)) != sources.end()) {
2720 /* XXX search MIDI or other searches here */
2726 boost::shared_ptr<Source>
2727 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2729 Glib::Mutex::Lock lm (source_lock);
2731 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2732 cerr << "comparing " << path << " with " << i->second->name() << endl;
2733 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2735 if (afs && afs->path() == path && chn == afs->channel()) {
2740 return boost::shared_ptr<Source>();
2744 Session::peak_path_from_audio_path (string audio_path) const
2749 res += PBD::basename_nosuffix (audio_path);
2756 Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
2759 string old_basename = PBD::basename_nosuffix (oldname);
2760 string new_legalized = legalize_for_path (newname);
2762 /* note: we know (or assume) the old path is already valid */
2766 /* destructive file sources have a name of the form:
2768 /path/to/Tnnnn-NAME(%[LR])?.wav
2770 the task here is to replace NAME with the new name.
2773 /* find last slash */
2777 string::size_type slash;
2778 string::size_type dash;
2780 if ((slash = path.find_last_of ('/')) == string::npos) {
2784 dir = path.substr (0, slash+1);
2786 /* '-' is not a legal character for the NAME part of the path */
2788 if ((dash = path.find_last_of ('-')) == string::npos) {
2792 prefix = path.substr (slash+1, dash-(slash+1));
2797 path += new_legalized;
2798 path += ".wav"; /* XXX gag me with a spoon */
2802 /* non-destructive file sources have a name of the form:
2804 /path/to/NAME-nnnnn(%[LR])?.wav
2806 the task here is to replace NAME with the new name.
2811 string::size_type slash;
2812 string::size_type dash;
2813 string::size_type postfix;
2815 /* find last slash */
2817 if ((slash = path.find_last_of ('/')) == string::npos) {
2821 dir = path.substr (0, slash+1);
2823 /* '-' is not a legal character for the NAME part of the path */
2825 if ((dash = path.find_last_of ('-')) == string::npos) {
2829 suffix = path.substr (dash+1);
2831 // Suffix is now everything after the dash. Now we need to eliminate
2832 // the nnnnn part, which is done by either finding a '%' or a '.'
2834 postfix = suffix.find_last_of ("%");
2835 if (postfix == string::npos) {
2836 postfix = suffix.find_last_of ('.');
2839 if (postfix != string::npos) {
2840 suffix = suffix.substr (postfix);
2842 error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
2846 const uint32_t limit = 10000;
2847 char buf[PATH_MAX+1];
2849 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
2851 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
2853 if (access (buf, F_OK) != 0) {
2861 error << "FATAL ERROR! Could not find a " << endl;
2870 Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
2874 char buf[PATH_MAX+1];
2875 const uint32_t limit = 10000;
2879 legalized = legalize_for_path (name);
2881 /* find a "version" of the file name that doesn't exist in
2882 any of the possible directories.
2885 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
2887 vector<space_and_path>::iterator i;
2888 uint32_t existing = 0;
2890 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2894 spath += sound_dir (false);
2898 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2899 } else if (nchan == 2) {
2901 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
2903 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
2905 } else if (nchan < 26) {
2906 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
2908 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
2917 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2918 } else if (nchan == 2) {
2920 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
2922 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
2924 } else if (nchan < 26) {
2925 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
2927 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
2931 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
2937 if (existing == 0) {
2942 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
2944 throw failed_constructor();
2948 /* we now have a unique name for the file, but figure out where to
2954 spath = discover_best_sound_dir ();
2957 string::size_type pos = foo.find_last_of ('/');
2959 if (pos == string::npos) {
2962 spath += foo.substr (pos + 1);
2968 boost::shared_ptr<AudioFileSource>
2969 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
2971 string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive);
2972 return boost::dynamic_pointer_cast<AudioFileSource> (
2973 SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate()));
2976 // FIXME: _terrible_ code duplication
2978 Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive)
2981 string old_basename = PBD::basename_nosuffix (oldname);
2982 string new_legalized = legalize_for_path (newname);
2984 /* note: we know (or assume) the old path is already valid */
2988 /* destructive file sources have a name of the form:
2990 /path/to/Tnnnn-NAME(%[LR])?.wav
2992 the task here is to replace NAME with the new name.
2995 /* find last slash */
2999 string::size_type slash;
3000 string::size_type dash;
3002 if ((slash = path.find_last_of ('/')) == string::npos) {
3006 dir = path.substr (0, slash+1);
3008 /* '-' is not a legal character for the NAME part of the path */
3010 if ((dash = path.find_last_of ('-')) == string::npos) {
3014 prefix = path.substr (slash+1, dash-(slash+1));
3019 path += new_legalized;
3020 path += ".mid"; /* XXX gag me with a spoon */
3024 /* non-destructive file sources have a name of the form:
3026 /path/to/NAME-nnnnn(%[LR])?.wav
3028 the task here is to replace NAME with the new name.
3033 string::size_type slash;
3034 string::size_type dash;
3035 string::size_type postfix;
3037 /* find last slash */
3039 if ((slash = path.find_last_of ('/')) == string::npos) {
3043 dir = path.substr (0, slash+1);
3045 /* '-' is not a legal character for the NAME part of the path */
3047 if ((dash = path.find_last_of ('-')) == string::npos) {
3051 suffix = path.substr (dash+1);
3053 // Suffix is now everything after the dash. Now we need to eliminate
3054 // the nnnnn part, which is done by either finding a '%' or a '.'
3056 postfix = suffix.find_last_of ("%");
3057 if (postfix == string::npos) {
3058 postfix = suffix.find_last_of ('.');
3061 if (postfix != string::npos) {
3062 suffix = suffix.substr (postfix);
3064 error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl;
3068 const uint32_t limit = 10000;
3069 char buf[PATH_MAX+1];
3071 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3073 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3075 if (access (buf, F_OK) != 0) {
3083 error << "FATAL ERROR! Could not find a " << endl;
3092 Session::midi_path_from_name (string name)
3096 char buf[PATH_MAX+1];
3097 const uint32_t limit = 10000;
3101 legalized = legalize_for_path (name);
3103 /* find a "version" of the file name that doesn't exist in
3104 any of the possible directories.
3107 for (cnt = 1; cnt <= limit; ++cnt) {
3109 vector<space_and_path>::iterator i;
3110 uint32_t existing = 0;
3112 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3116 // FIXME: different directory from audio?
3117 spath += sound_dir(false) + "/" + legalized;
3119 snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
3121 if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
3126 if (existing == 0) {
3131 error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
3132 throw failed_constructor();
3136 /* we now have a unique name for the file, but figure out where to
3142 // FIXME: different directory than audio?
3143 spath = discover_best_sound_dir ();
3146 string::size_type pos = foo.find_last_of ('/');
3148 if (pos == string::npos) {
3151 spath += foo.substr (pos + 1);
3157 boost::shared_ptr<MidiSource>
3158 Session::create_midi_source_for_session (MidiDiskstream& ds)
3160 string spath = midi_path_from_name (ds.name());
3162 return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
3166 /* Playlist management */
3168 boost::shared_ptr<Playlist>
3169 Session::playlist_by_name (string name)
3171 Glib::Mutex::Lock lm (playlist_lock);
3172 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3173 if ((*i)->name() == name) {
3177 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3178 if ((*i)->name() == name) {
3183 return boost::shared_ptr<Playlist>();
3187 Session::add_playlist (boost::shared_ptr<Playlist> playlist)
3189 if (playlist->hidden()) {
3194 Glib::Mutex::Lock lm (playlist_lock);
3195 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3196 playlists.insert (playlists.begin(), playlist);
3197 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3198 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3204 PlaylistAdded (playlist); /* EMIT SIGNAL */
3208 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3211 Glib::Mutex::Lock lm (playlist_lock);
3212 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3215 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3222 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3224 boost::shared_ptr<Playlist> pl(wpl.lock());
3230 PlaylistList::iterator x;
3233 /* its not supposed to be visible */
3238 Glib::Mutex::Lock lm (playlist_lock);
3242 unused_playlists.insert (pl);
3244 if ((x = playlists.find (pl)) != playlists.end()) {
3245 playlists.erase (x);
3251 playlists.insert (pl);
3253 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3254 unused_playlists.erase (x);
3261 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3263 if (_state_of_the_state & Deletion) {
3267 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3274 Glib::Mutex::Lock lm (playlist_lock);
3276 PlaylistList::iterator i;
3278 i = find (playlists.begin(), playlists.end(), playlist);
3279 if (i != playlists.end()) {
3280 playlists.erase (i);
3283 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3284 if (i != unused_playlists.end()) {
3285 unused_playlists.erase (i);
3292 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3296 Session::set_audition (boost::shared_ptr<Region> r)
3298 pending_audition_region = r;
3299 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3300 schedule_butler_transport_work ();
3304 Session::audition_playlist ()
3306 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3307 ev->region.reset ();
3312 Session::non_realtime_set_audition ()
3314 if (!pending_audition_region) {
3315 auditioner->audition_current_playlist ();
3317 auditioner->audition_region (pending_audition_region);
3318 pending_audition_region.reset ();
3320 AuditionActive (true); /* EMIT SIGNAL */
3324 Session::audition_region (boost::shared_ptr<Region> r)
3326 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3332 Session::cancel_audition ()
3334 if (auditioner->active()) {
3335 auditioner->cancel_audition ();
3336 AuditionActive (false); /* EMIT SIGNAL */
3341 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3343 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3347 Session::remove_empty_sounds ()
3349 PathScanner scanner;
3351 vector<string *>* possible_audiofiles = scanner (sound_dir(), Config->get_possible_audio_file_regexp (), false, true);
3353 Glib::Mutex::Lock lm (source_lock);
3355 regex_t compiled_tape_track_pattern;
3358 if ((err = regcomp (&compiled_tape_track_pattern, "/T[0-9][0-9][0-9][0-9]-", REG_EXTENDED|REG_NOSUB))) {
3362 regerror (err, &compiled_tape_track_pattern, msg, sizeof (msg));
3364 error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg;
3368 for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
3370 /* never remove files that appear to be a tape track */
3372 if (regexec (&compiled_tape_track_pattern, (*i)->c_str(), 0, 0, 0) == 0) {
3377 if (AudioFileSource::is_empty (*this, *(*i))) {
3379 unlink ((*i)->c_str());
3381 string peak_path = peak_path_from_audio_path (**i);
3382 unlink (peak_path.c_str());
3388 delete possible_audiofiles;
3392 Session::is_auditioning () const
3394 /* can be called before we have an auditioner object */
3396 return auditioner->active();
3403 Session::set_all_solo (bool yn)
3405 shared_ptr<RouteList> r = routes.reader ();
3407 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3408 if (!(*i)->hidden()) {
3409 (*i)->set_solo (yn, this);
3417 Session::set_all_mute (bool yn)
3419 shared_ptr<RouteList> r = routes.reader ();
3421 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3422 if (!(*i)->hidden()) {
3423 (*i)->set_mute (yn, this);
3431 Session::n_diskstreams () const
3435 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3437 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3438 if (!(*i)->hidden()) {
3446 Session::graph_reordered ()
3448 /* don't do this stuff if we are setting up connections
3449 from a set_state() call or creating new tracks.
3452 if (_state_of_the_state & InitialConnecting) {
3456 /* every track/bus asked for this to be handled but it was deferred because
3457 we were connecting. do it now.
3460 request_input_change_handling ();
3464 /* force all diskstreams to update their capture offset values to
3465 reflect any changes in latencies within the graph.
3468 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3470 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3471 (*i)->set_capture_offset ();
3476 Session::record_disenable_all ()
3478 record_enable_change_all (false);
3482 Session::record_enable_all ()
3484 record_enable_change_all (true);
3488 Session::record_enable_change_all (bool yn)
3490 shared_ptr<RouteList> r = routes.reader ();
3492 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3495 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3496 at->set_record_enable (yn, this);
3500 /* since we don't keep rec-enable state, don't mark session dirty */
3504 Session::add_redirect (Redirect* redirect)
3508 PortInsert* port_insert;
3509 PluginInsert* plugin_insert;
3511 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3512 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3513 _port_inserts.insert (_port_inserts.begin(), port_insert);
3514 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3515 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3517 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3520 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3521 _sends.insert (_sends.begin(), send);
3523 fatal << _("programming error: unknown type of Redirect created!") << endmsg;
3527 redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
3533 Session::remove_redirect (Redirect* redirect)
3537 PortInsert* port_insert;
3538 PluginInsert* plugin_insert;
3540 if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
3541 if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
3542 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3543 if (x != _port_inserts.end()) {
3544 insert_bitset[port_insert->bit_slot()] = false;
3545 _port_inserts.erase (x);
3547 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
3548 _plugin_inserts.remove (plugin_insert);
3550 fatal << string_compose (_("programming error: %1"),
3551 X_("unknown type of Insert deleted!"))
3555 } else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
3556 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3557 if (x != _sends.end()) {
3558 send_bitset[send->bit_slot()] = false;
3562 fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
3570 Session::available_capture_duration ()
3572 float sample_bytes_on_disk = 4.0; // keep gcc happy
3574 switch (Config->get_native_file_data_format()) {
3576 sample_bytes_on_disk = 4.0;
3580 sample_bytes_on_disk = 3.0;
3584 /* impossible, but keep some gcc versions happy */
3585 fatal << string_compose (_("programming error: %1"),
3586 X_("illegal native file data format"))
3591 double scale = 4096.0 / sample_bytes_on_disk;
3593 if (_total_free_4k_blocks * scale > (double) max_frames) {
3597 return (nframes_t) floor (_total_free_4k_blocks * scale);
3601 Session::add_connection (ARDOUR::Connection* connection)
3604 Glib::Mutex::Lock guard (connection_lock);
3605 _connections.push_back (connection);
3608 ConnectionAdded (connection); /* EMIT SIGNAL */
3614 Session::remove_connection (ARDOUR::Connection* connection)
3616 bool removed = false;
3619 Glib::Mutex::Lock guard (connection_lock);
3620 ConnectionList::iterator i = find (_connections.begin(), _connections.end(), connection);
3622 if (i != _connections.end()) {
3623 _connections.erase (i);
3629 ConnectionRemoved (connection); /* EMIT SIGNAL */
3635 ARDOUR::Connection *
3636 Session::connection_by_name (string name) const
3638 Glib::Mutex::Lock lm (connection_lock);
3640 for (ConnectionList::const_iterator i = _connections.begin(); i != _connections.end(); ++i) {
3641 if ((*i)->name() == name) {
3650 Session::tempo_map_changed (Change ignored)
3656 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3657 * the given count with the current block size.
3660 Session::ensure_buffers (ChanCount howmany)
3662 // FIXME: NASTY assumption (midi block size == audio block size)
3663 _scratch_buffers->ensure_buffers(howmany, current_block_size);
3664 _send_buffers->ensure_buffers(howmany, current_block_size);
3665 _silent_buffers->ensure_buffers(howmany, current_block_size);
3667 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3671 Session::next_insert_id ()
3673 /* this doesn't really loop forever. just think about it */
3676 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3677 if (!insert_bitset[n]) {
3678 insert_bitset[n] = true;
3684 /* none available, so resize and try again */
3686 insert_bitset.resize (insert_bitset.size() + 16, false);
3691 Session::next_send_id ()
3693 /* this doesn't really loop forever. just think about it */
3696 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3697 if (!send_bitset[n]) {
3698 send_bitset[n] = true;
3704 /* none available, so resize and try again */
3706 send_bitset.resize (send_bitset.size() + 16, false);
3711 Session::mark_send_id (uint32_t id)
3713 if (id >= send_bitset.size()) {
3714 send_bitset.resize (id+16, false);
3716 if (send_bitset[id]) {
3717 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3719 send_bitset[id] = true;
3723 Session::mark_insert_id (uint32_t id)
3725 if (id >= insert_bitset.size()) {
3726 insert_bitset.resize (id+16, false);
3728 if (insert_bitset[id]) {
3729 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3731 insert_bitset[id] = true;
3734 /* Named Selection management */
3737 Session::named_selection_by_name (string name)
3739 Glib::Mutex::Lock lm (named_selection_lock);
3740 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3741 if ((*i)->name == name) {
3749 Session::add_named_selection (NamedSelection* named_selection)
3752 Glib::Mutex::Lock lm (named_selection_lock);
3753 named_selections.insert (named_selections.begin(), named_selection);
3756 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3762 NamedSelectionAdded (); /* EMIT SIGNAL */
3766 Session::remove_named_selection (NamedSelection* named_selection)
3768 bool removed = false;
3771 Glib::Mutex::Lock lm (named_selection_lock);
3773 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3775 if (i != named_selections.end()) {
3777 named_selections.erase (i);
3784 NamedSelectionRemoved (); /* EMIT SIGNAL */
3789 Session::reset_native_file_format ()
3791 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3793 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3794 (*i)->reset_write_sources (false);
3799 Session::route_name_unique (string n) const
3801 shared_ptr<RouteList> r = routes.reader ();
3803 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
3804 if ((*i)->name() == n) {
3813 Session::n_playlists () const
3815 Glib::Mutex::Lock lm (playlist_lock);
3816 return playlists.size();
3820 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
3822 if (!force && howmany <= _npan_buffers) {
3826 if (_pan_automation_buffer) {
3828 for (uint32_t i = 0; i < _npan_buffers; ++i) {
3829 delete [] _pan_automation_buffer[i];
3832 delete [] _pan_automation_buffer;
3835 _pan_automation_buffer = new pan_t*[howmany];
3837 for (uint32_t i = 0; i < howmany; ++i) {
3838 _pan_automation_buffer[i] = new pan_t[nframes];
3841 _npan_buffers = howmany;
3845 Session::freeze (InterThreadInfo& itt)
3847 shared_ptr<RouteList> r = routes.reader ();
3849 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3853 if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
3854 /* XXX this is wrong because itt.progress will keep returning to zero at the start
3865 Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len,
3866 bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
3869 boost::shared_ptr<Playlist> playlist;
3870 boost::shared_ptr<AudioFileSource> fsource;
3872 char buf[PATH_MAX+1];
3874 ChanCount nchans(track.audio_diskstream()->n_channels());
3876 nframes_t this_chunk;
3880 // any bigger than this seems to cause stack overflows in called functions
3881 const nframes_t chunk_size = (128 * 1024)/4;
3883 g_atomic_int_set (&processing_prohibited, 1);
3885 /* call tree *MUST* hold route_lock */
3887 if ((playlist = track.diskstream()->playlist()) == 0) {
3891 /* external redirects will be a problem */
3893 if (track.has_external_redirects()) {
3897 dir = discover_best_sound_dir ();
3899 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
3901 for (x = 0; x < 99999; ++x) {
3902 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
3903 if (access (buf, F_OK) != 0) {
3909 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
3914 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
3915 SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
3918 catch (failed_constructor& err) {
3919 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
3923 srcs.push_back (fsource);
3926 /* XXX need to flush all redirects */
3931 /* create a set of reasonably-sized buffers */
3932 buffers.ensure_buffers(nchans, chunk_size);
3933 buffers.set_count(nchans);
3935 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3936 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3938 afs->prepare_for_peakfile_writes ();
3941 while (to_do && !itt.cancel) {
3943 this_chunk = min (to_do, chunk_size);
3945 if (track.export_stuff (buffers, start, this_chunk)) {
3950 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
3951 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3954 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
3960 start += this_chunk;
3961 to_do -= this_chunk;
3963 itt.progress = (float) (1.0 - ((double) to_do / len));
3972 xnow = localtime (&now);
3974 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
3975 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3978 afs->update_header (position, *xnow, now);
3979 afs->flush_header ();
3983 /* construct a region to represent the bounced material */
3985 boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(),
3986 region_name_from_path (srcs.front()->name(), true));
3993 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
3994 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
3997 afs->mark_for_remove ();
4000 (*src)->drop_references ();
4004 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4005 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4008 afs->done_with_peakfile_writes ();
4012 g_atomic_int_set (&processing_prohibited, 0);
4018 Session::get_silent_buffers (ChanCount count)
4020 assert(_silent_buffers->available() >= count);
4021 _silent_buffers->set_count(count);
4023 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4024 for (size_t i=0; i < count.get(*t); ++i) {
4025 _silent_buffers->get(*t, i).clear();
4029 return *_silent_buffers;
4033 Session::get_scratch_buffers (ChanCount count)
4035 assert(_scratch_buffers->available() >= count);
4036 _scratch_buffers->set_count(count);
4037 return *_scratch_buffers;
4041 Session::get_send_buffers (ChanCount count)
4043 assert(_send_buffers->available() >= count);
4044 _send_buffers->set_count(count);
4045 return *_send_buffers;
4049 Session::ntracks () const
4052 shared_ptr<RouteList> r = routes.reader ();
4054 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4055 if (dynamic_cast<Track*> ((*i).get())) {
4064 Session::nbusses () const
4067 shared_ptr<RouteList> r = routes.reader ();
4069 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4070 if (dynamic_cast<Track*> ((*i).get()) == 0) {
4079 Session::add_automation_list(AutomationList *al)
4081 automation_lists[al->id()] = al;
4085 Session::compute_initial_length ()
4087 return _engine.frame_rate() * 60 * 5;