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>
36 #include <glibmm/fileutils.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"
44 #include "pbd/file_utils.h"
46 #include "ardour/analyser.h"
47 #include "ardour/audio_buffer.h"
48 #include "ardour/audio_diskstream.h"
49 #include "ardour/audio_track.h"
50 #include "ardour/audioengine.h"
51 #include "ardour/audiofilesource.h"
52 #include "ardour/audioplaylist.h"
53 #include "ardour/audioregion.h"
54 #include "ardour/auditioner.h"
55 #include "ardour/buffer_set.h"
56 #include "ardour/bundle.h"
57 #include "ardour/click.h"
58 #include "ardour/configuration.h"
59 #include "ardour/crossfade.h"
60 #include "ardour/cycle_timer.h"
61 #include "ardour/data_type.h"
62 #include "ardour/filename_extensions.h"
63 #include "ardour/io_processor.h"
64 #include "ardour/midi_diskstream.h"
65 #include "ardour/midi_playlist.h"
66 #include "ardour/midi_region.h"
67 #include "ardour/midi_track.h"
68 #include "ardour/named_selection.h"
69 #include "ardour/playlist.h"
70 #include "ardour/plugin_insert.h"
71 #include "ardour/port_insert.h"
72 #include "ardour/processor.h"
73 #include "ardour/recent_sessions.h"
74 #include "ardour/region_factory.h"
75 #include "ardour/return.h"
76 #include "ardour/route_group.h"
77 #include "ardour/send.h"
78 #include "ardour/session.h"
79 #include "ardour/session_directory.h"
80 #include "ardour/session_directory.h"
81 #include "ardour/session_metadata.h"
82 #include "ardour/slave.h"
83 #include "ardour/smf_source.h"
84 #include "ardour/source_factory.h"
85 #include "ardour/tape_file_matcher.h"
86 #include "ardour/tempo.h"
87 #include "ardour/utils.h"
92 using namespace ARDOUR;
94 using boost::shared_ptr;
96 bool Session::_disable_all_loaded_plugins = false;
98 sigc::signal<void,std::string> Session::Dialog;
99 sigc::signal<int> Session::AskAboutPendingState;
100 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
101 sigc::signal<void> Session::SendFeedback;
103 sigc::signal<void> Session::SMPTEOffsetChanged;
104 sigc::signal<void> Session::StartTimeChanged;
105 sigc::signal<void> Session::EndTimeChanged;
106 sigc::signal<void> Session::AutoBindingOn;
107 sigc::signal<void> Session::AutoBindingOff;
108 sigc::signal<void, std::string, std::string> Session::Exported;
110 Session::Session (AudioEngine &eng,
111 const string& fullpath,
112 const string& snapshot_name,
119 _requested_return_frame (-1),
120 _scratch_buffers(new BufferSet()),
121 _silent_buffers(new BufferSet()),
122 _mix_buffers(new BufferSet()),
124 _mmc_port (default_mmc_port),
125 _mtc_port (default_mtc_port),
126 _midi_port (default_midi_port),
127 _midi_clock_port (default_midi_clock_port),
128 _session_dir (new SessionDirectory(fullpath)),
129 pending_events (2048),
131 butler_mixdown_buffer (0),
132 butler_gain_buffer (0),
133 post_transport_work((PostTransportWork)0),
134 _send_smpte_update (false),
135 midi_thread (pthread_t (0)),
136 midi_requests (128), // the size of this should match the midi request pool size
137 diskstreams (new DiskstreamList),
138 routes (new RouteList),
139 _total_free_4k_blocks (0),
140 _bundles (new BundleList),
141 _bundle_xml_node (0),
144 click_emphasis_data (0),
146 _metadata (new SessionMetadata()),
147 _have_rec_enabled_diskstream (false)
152 if (!eng.connected()) {
153 throw failed_constructor();
156 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
158 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
159 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
161 first_stage_init (fullpath, snapshot_name);
163 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
166 if (create (new_session, mix_template, compute_initial_length())) {
168 throw failed_constructor ();
172 if (second_stage_init (new_session)) {
174 throw failed_constructor ();
177 store_recent_sessions(_name, _path);
179 bool was_dirty = dirty();
181 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
183 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
186 DirtyChanged (); /* EMIT SIGNAL */
190 Session::Session (AudioEngine &eng,
192 string snapshot_name,
193 AutoConnectOption input_ac,
194 AutoConnectOption output_ac,
195 uint32_t control_out_channels,
196 uint32_t master_out_channels,
197 uint32_t requested_physical_in,
198 uint32_t requested_physical_out,
199 nframes_t initial_length)
205 _requested_return_frame (-1),
206 _scratch_buffers(new BufferSet()),
207 _silent_buffers(new BufferSet()),
208 _mix_buffers(new BufferSet()),
210 _mmc_port (default_mmc_port),
211 _mtc_port (default_mtc_port),
212 _midi_port (default_midi_port),
213 _midi_clock_port (default_midi_clock_port),
214 _session_dir ( new SessionDirectory(fullpath)),
215 pending_events (2048),
217 butler_mixdown_buffer (0),
218 butler_gain_buffer (0),
219 post_transport_work((PostTransportWork)0),
220 _send_smpte_update (false),
221 midi_thread (pthread_t (0)),
223 diskstreams (new DiskstreamList),
224 routes (new RouteList),
225 _total_free_4k_blocks (0),
226 _bundles (new BundleList),
227 _bundle_xml_node (0),
228 _click_io ((IO *) 0),
230 click_emphasis_data (0),
232 _metadata (new SessionMetadata()),
233 _have_rec_enabled_diskstream (false)
237 if (!eng.connected()) {
238 throw failed_constructor();
241 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
243 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
244 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
246 if (n_physical_inputs) {
247 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
250 if (n_physical_outputs) {
251 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
254 first_stage_init (fullpath, snapshot_name);
256 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
259 if (create (new_session, string(), initial_length)) {
261 throw failed_constructor ();
266 /* set up Master Out and Control Out if necessary */
271 if (control_out_channels) {
272 ChanCount count(DataType::AUDIO, control_out_channels);
273 shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut,
274 DataType::AUDIO, count, count));
275 r->set_remote_control_id (control_id++);
280 if (master_out_channels) {
281 ChanCount count(DataType::AUDIO, master_out_channels);
282 cerr << "new MO with " << count << endl;
283 shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut,
284 DataType::AUDIO, count, count));
285 r->set_remote_control_id (control_id);
289 /* prohibit auto-connect to master, because there isn't one */
290 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
294 add_routes (rl, false);
299 Config->set_input_auto_connect (input_ac);
300 Config->set_output_auto_connect (output_ac);
302 if (second_stage_init (new_session)) {
304 throw failed_constructor ();
307 store_recent_sessions (_name, _path);
309 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
311 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
322 /* if we got to here, leaving pending capture state around
326 remove_pending_capture_state ();
328 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
330 _engine.remove_session ();
332 GoingAway (); /* EMIT SIGNAL */
338 /* clear history so that no references to objects are held any more */
342 /* clear state tree so that no references to objects are held any more */
346 terminate_butler_thread ();
347 //terminate_midi_thread ();
349 if (click_data != default_click) {
350 delete [] click_data;
353 if (click_emphasis_data != default_click_emphasis) {
354 delete [] click_emphasis_data;
359 delete _scratch_buffers;
360 delete _silent_buffers;
363 AudioDiskstream::free_working_buffers();
365 Route::SyncOrderKeys.clear();
367 #undef TRACK_DESTRUCTION
368 #ifdef TRACK_DESTRUCTION
369 cerr << "delete named selections\n";
370 #endif /* TRACK_DESTRUCTION */
371 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
372 NamedSelectionList::iterator tmp;
381 #ifdef TRACK_DESTRUCTION
382 cerr << "delete playlists\n";
383 #endif /* TRACK_DESTRUCTION */
384 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
385 PlaylistList::iterator tmp;
390 (*i)->drop_references ();
395 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
396 PlaylistList::iterator tmp;
401 (*i)->drop_references ();
407 unused_playlists.clear ();
409 #ifdef TRACK_DESTRUCTION
410 cerr << "delete regions\n";
411 #endif /* TRACK_DESTRUCTION */
413 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
414 RegionList::iterator tmp;
419 i->second->drop_references ();
426 #ifdef TRACK_DESTRUCTION
427 cerr << "delete routes\n";
428 #endif /* TRACK_DESTRUCTION */
430 RCUWriter<RouteList> writer (routes);
431 boost::shared_ptr<RouteList> r = writer.get_copy ();
432 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
433 (*i)->drop_references ();
436 /* writer goes out of scope and updates master */
441 #ifdef TRACK_DESTRUCTION
442 cerr << "delete diskstreams\n";
443 #endif /* TRACK_DESTRUCTION */
445 RCUWriter<DiskstreamList> dwriter (diskstreams);
446 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
447 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
448 (*i)->drop_references ();
452 diskstreams.flush ();
454 #ifdef TRACK_DESTRUCTION
455 cerr << "delete audio sources\n";
456 #endif /* TRACK_DESTRUCTION */
457 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
458 SourceMap::iterator tmp;
463 i->second->drop_references ();
469 #ifdef TRACK_DESTRUCTION
470 cerr << "delete mix groups\n";
471 #endif /* TRACK_DESTRUCTION */
472 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
473 list<RouteGroup*>::iterator tmp;
483 #ifdef TRACK_DESTRUCTION
484 cerr << "delete edit groups\n";
485 #endif /* TRACK_DESTRUCTION */
486 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
487 list<RouteGroup*>::iterator tmp;
497 delete [] butler_mixdown_buffer;
498 delete [] butler_gain_buffer;
500 Crossfade::set_buffer_size (0);
506 Session::set_worst_io_latencies ()
508 _worst_output_latency = 0;
509 _worst_input_latency = 0;
511 if (!_engine.connected()) {
515 boost::shared_ptr<RouteList> r = routes.reader ();
517 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
518 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
519 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
524 Session::when_engine_running ()
526 string first_physical_output;
528 BootMessage (_("Set block size and sample rate"));
530 set_block_size (_engine.frames_per_cycle());
531 set_frame_rate (_engine.frame_rate());
533 BootMessage (_("Using configuration"));
535 Config->map_parameters (mem_fun (*this, &Session::config_changed));
537 /* every time we reconnect, recompute worst case output latencies */
539 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
541 if (synced_to_jack()) {
542 _engine.transport_stop ();
545 if (Config->get_jack_time_master()) {
546 _engine.transport_locate (_transport_frame);
554 _click_io.reset (new ClickIO (*this, "click"));
556 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
558 /* existing state for Click */
560 if (_click_io->set_state (*child->children().front()) == 0) {
562 _clicking = Config->get_clicking ();
566 error << _("could not setup Click I/O") << endmsg;
572 /* default state for Click: dual-mono to first 2 physical outputs */
574 for (int physport = 0; physport < 2; ++physport) {
575 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
577 if (physical_output.length()) {
578 if (_click_io->add_output_port (physical_output, this)) {
579 // relax, even though its an error
584 if (_click_io->n_outputs () > ChanCount::ZERO) {
585 _clicking = Config->get_clicking ();
590 catch (failed_constructor& err) {
591 error << _("cannot setup Click I/O") << endmsg;
594 BootMessage (_("Compute I/O Latencies"));
596 set_worst_io_latencies ();
599 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
602 BootMessage (_("Set up standard connections"));
604 /* Create a set of Bundle objects that map
605 to the physical I/O currently available. We create both
606 mono and stereo bundles, so that the common cases of mono
607 and stereo tracks get bundles to put in their mixer strip
608 in / out menus. There may be a nicer way of achieving that;
609 it doesn't really scale that well to higher channel counts
612 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
614 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
616 shared_ptr<Bundle> c (new Bundle (buf, true));
617 c->add_channel (_("mono"));
618 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
623 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
624 if (np + 1 < n_physical_outputs) {
626 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
627 shared_ptr<Bundle> c (new Bundle (buf, true));
628 c->add_channel (_("L"));
629 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
630 c->add_channel (_("R"));
631 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
637 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
639 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
641 shared_ptr<Bundle> c (new Bundle (buf, false));
642 c->add_channel (_("mono"));
643 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
648 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
649 if (np + 1 < n_physical_inputs) {
651 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
653 shared_ptr<Bundle> c (new Bundle (buf, false));
654 c->add_channel (_("L"));
655 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
656 c->add_channel (_("R"));
657 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
663 /* create master/control ports */
667 /* force the master to ignore any later call to this
669 if (_master_out->pending_state_node) {
670 _master_out->ports_became_legal();
673 /* create ports, without any connections
675 _master_out->ensure_io (_master_out->input_minimum (), _master_out->output_minimum (), true, this);
677 /* if requested auto-connect the outputs to the first N physical ports.
679 if (Config->get_auto_connect_master()) {
680 uint32_t limit = _master_out->n_outputs().n_total();
682 for (uint32_t n = 0; n < limit; ++n) {
683 Port* p = _master_out->output (n);
684 string connect_to = _engine.get_nth_physical_output (DataType (p->type()), n);
686 if (!connect_to.empty()) {
687 if (_master_out->connect_output (p, connect_to, this)) {
688 error << string_compose (_("cannot connect master output %1 to %2"), n, connect_to)
697 BootMessage (_("Setup signal flow and plugins"));
701 /* catch up on send+insert cnts */
703 BootMessage (_("Catch up with send/insert state"));
707 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
710 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
711 if (id > insert_cnt) {
719 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
722 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
730 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
732 /* hook us up to the engine */
734 BootMessage (_("Connect to engine"));
736 _engine.set_session (this);
740 Session::hookup_io ()
742 /* stop graph reordering notifications from
743 causing resorts, etc.
746 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
751 /* we delay creating the auditioner till now because
752 it makes its own connections to ports.
753 the engine has to be running for this to work.
757 auditioner.reset (new Auditioner (*this));
760 catch (failed_constructor& err) {
761 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
765 /* Tell all IO objects to create their ports */
769 /* Connect track to listen/solo etc. busses XXX generalize this beyond control_out */
773 _control_out->ensure_io (_control_out->input_minimum(), _control_out->output_minimum(), false, this);
775 boost::shared_ptr<RouteList> r = routes.reader ();
777 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
779 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*x);
782 t->listen_via (_control_out, X_("listen"));
787 /* load bundles, which we may have postponed earlier on */
788 if (_bundle_xml_node) {
789 load_bundles (*_bundle_xml_node);
790 delete _bundle_xml_node;
793 /* Tell all IO objects to connect themselves together */
795 IO::enable_connecting ();
797 /* Now reset all panners */
799 IO::reset_panners ();
801 /* Anyone who cares about input state, wake up and do something */
803 IOConnectionsComplete (); /* EMIT SIGNAL */
805 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
808 /* now handle the whole enchilada as if it was one
814 /* update mixer solo state */
820 Session::playlist_length_changed ()
822 /* we can't just increase end_location->end() if pl->get_maximum_extent()
823 if larger. if the playlist used to be the longest playlist,
824 and its now shorter, we have to decrease end_location->end(). hence,
825 we have to iterate over all diskstreams and check the
826 playlists currently in use.
832 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
834 boost::shared_ptr<Playlist> playlist;
836 if ((playlist = dstream->playlist()) != 0) {
837 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
840 /* see comment in playlist_length_changed () */
845 Session::record_enabling_legal () const
847 /* this used to be in here, but survey says.... we don't need to restrict it */
848 // if (record_status() == Recording) {
852 if (Config->get_all_safe()) {
859 Session::reset_input_monitor_state ()
861 if (transport_rolling()) {
863 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
865 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
866 if ((*i)->record_enabled ()) {
867 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
868 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
872 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
874 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
875 if ((*i)->record_enabled ()) {
876 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
877 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
884 Session::auto_punch_start_changed (Location* location)
886 replace_event (Event::PunchIn, location->start());
888 if (get_record_enabled() && Config->get_punch_in()) {
889 /* capture start has been changed, so save new pending state */
890 save_state ("", true);
895 Session::auto_punch_end_changed (Location* location)
897 nframes_t when_to_stop = location->end();
898 // when_to_stop += _worst_output_latency + _worst_input_latency;
899 replace_event (Event::PunchOut, when_to_stop);
903 Session::auto_punch_changed (Location* location)
905 nframes_t when_to_stop = location->end();
907 replace_event (Event::PunchIn, location->start());
908 //when_to_stop += _worst_output_latency + _worst_input_latency;
909 replace_event (Event::PunchOut, when_to_stop);
913 Session::auto_loop_changed (Location* location)
915 replace_event (Event::AutoLoop, location->end(), location->start());
917 if (transport_rolling() && play_loop) {
919 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
921 if (_transport_frame > location->end()) {
922 // relocate to beginning of loop
923 clear_events (Event::LocateRoll);
925 request_locate (location->start(), true);
928 else if (Config->get_seamless_loop() && !loop_changing) {
930 // schedule a locate-roll to refill the diskstreams at the
932 loop_changing = true;
934 if (location->end() > last_loopend) {
935 clear_events (Event::LocateRoll);
936 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
943 last_loopend = location->end();
947 Session::set_auto_punch_location (Location* location)
951 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
952 auto_punch_start_changed_connection.disconnect();
953 auto_punch_end_changed_connection.disconnect();
954 auto_punch_changed_connection.disconnect();
955 existing->set_auto_punch (false, this);
956 remove_event (existing->start(), Event::PunchIn);
957 clear_events (Event::PunchOut);
958 auto_punch_location_changed (0);
967 if (location->end() <= location->start()) {
968 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
972 auto_punch_start_changed_connection.disconnect();
973 auto_punch_end_changed_connection.disconnect();
974 auto_punch_changed_connection.disconnect();
976 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
977 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
978 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
980 location->set_auto_punch (true, this);
983 auto_punch_changed (location);
985 auto_punch_location_changed (location);
989 Session::set_auto_loop_location (Location* location)
993 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
994 auto_loop_start_changed_connection.disconnect();
995 auto_loop_end_changed_connection.disconnect();
996 auto_loop_changed_connection.disconnect();
997 existing->set_auto_loop (false, this);
998 remove_event (existing->end(), Event::AutoLoop);
999 auto_loop_location_changed (0);
1004 if (location == 0) {
1008 if (location->end() <= location->start()) {
1009 error << _("Session: you can't use a mark for auto loop") << endmsg;
1013 last_loopend = location->end();
1015 auto_loop_start_changed_connection.disconnect();
1016 auto_loop_end_changed_connection.disconnect();
1017 auto_loop_changed_connection.disconnect();
1019 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1020 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1021 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1023 location->set_auto_loop (true, this);
1025 /* take care of our stuff first */
1027 auto_loop_changed (location);
1029 /* now tell everyone else */
1031 auto_loop_location_changed (location);
1035 Session::locations_added (Location* ignored)
1041 Session::locations_changed ()
1043 _locations.apply (*this, &Session::handle_locations_changed);
1047 Session::handle_locations_changed (Locations::LocationList& locations)
1049 Locations::LocationList::iterator i;
1051 bool set_loop = false;
1052 bool set_punch = false;
1054 for (i = locations.begin(); i != locations.end(); ++i) {
1058 if (location->is_auto_punch()) {
1059 set_auto_punch_location (location);
1062 if (location->is_auto_loop()) {
1063 set_auto_loop_location (location);
1067 if (location->is_start()) {
1068 start_location = location;
1070 if (location->is_end()) {
1071 end_location = location;
1076 set_auto_loop_location (0);
1079 set_auto_punch_location (0);
1086 Session::enable_record ()
1088 /* XXX really atomic compare+swap here */
1089 if (g_atomic_int_get (&_record_status) != Recording) {
1090 g_atomic_int_set (&_record_status, Recording);
1091 _last_record_location = _transport_frame;
1092 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1094 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1095 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1096 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1097 if ((*i)->record_enabled ()) {
1098 (*i)->monitor_input (true);
1103 RecordStateChanged ();
1108 Session::disable_record (bool rt_context, bool force)
1112 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1114 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1115 g_atomic_int_set (&_record_status, Disabled);
1117 if (rs == Recording) {
1118 g_atomic_int_set (&_record_status, Enabled);
1122 // FIXME: timestamp correct? [DR]
1123 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1124 // does this /need/ to be sent in all cases?
1126 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1128 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1129 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1131 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1132 if ((*i)->record_enabled ()) {
1133 (*i)->monitor_input (false);
1138 RecordStateChanged (); /* emit signal */
1141 remove_pending_capture_state ();
1147 Session::step_back_from_record ()
1149 /* XXX really atomic compare+swap here */
1150 if (g_atomic_int_get (&_record_status) == Recording) {
1151 g_atomic_int_set (&_record_status, Enabled);
1153 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1154 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1156 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1157 if ((*i)->record_enabled ()) {
1158 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1159 (*i)->monitor_input (false);
1167 Session::maybe_enable_record ()
1169 g_atomic_int_set (&_record_status, Enabled);
1171 /* this function is currently called from somewhere other than an RT thread.
1172 this save_state() call therefore doesn't impact anything.
1175 save_state ("", true);
1177 if (_transport_speed) {
1178 if (!Config->get_punch_in()) {
1182 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1183 RecordStateChanged (); /* EMIT SIGNAL */
1190 Session::audible_frame () const
1196 /* the first of these two possible settings for "offset"
1197 mean that the audible frame is stationary until
1198 audio emerges from the latency compensation
1201 the second means that the audible frame is stationary
1202 until audio would emerge from a physical port
1203 in the absence of any plugin latency compensation
1206 offset = _worst_output_latency;
1208 if (offset > current_block_size) {
1209 offset -= current_block_size;
1211 /* XXX is this correct? if we have no external
1212 physical connections and everything is internal
1213 then surely this is zero? still, how
1214 likely is that anyway?
1216 offset = current_block_size;
1219 if (synced_to_jack()) {
1220 tf = _engine.transport_frame();
1222 tf = _transport_frame;
1227 if (!non_realtime_work_pending()) {
1231 /* check to see if we have passed the first guaranteed
1232 audible frame past our last start position. if not,
1233 return that last start point because in terms
1234 of audible frames, we have not moved yet.
1237 if (_transport_speed > 0.0f) {
1239 if (!play_loop || !have_looped) {
1240 if (tf < _last_roll_location + offset) {
1241 return _last_roll_location;
1249 } else if (_transport_speed < 0.0f) {
1251 /* XXX wot? no backward looping? */
1253 if (tf > _last_roll_location - offset) {
1254 return _last_roll_location;
1266 Session::set_frame_rate (nframes_t frames_per_second)
1268 /** \fn void Session::set_frame_size(nframes_t)
1269 the AudioEngine object that calls this guarantees
1270 that it will not be called while we are also in
1271 ::process(). Its fine to do things that block
1275 _base_frame_rate = frames_per_second;
1279 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1283 // XXX we need some equivalent to this, somehow
1284 // SndFileSource::setup_standard_crossfades (frames_per_second);
1288 /* XXX need to reset/reinstantiate all LADSPA plugins */
1292 Session::set_block_size (nframes_t nframes)
1294 /* the AudioEngine guarantees
1295 that it will not be called while we are also in
1296 ::process(). It is therefore fine to do things that block
1301 current_block_size = nframes;
1303 ensure_buffers(_scratch_buffers->available());
1305 delete [] _gain_automation_buffer;
1306 _gain_automation_buffer = new gain_t[nframes];
1308 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1310 boost::shared_ptr<RouteList> r = routes.reader ();
1312 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1313 (*i)->set_block_size (nframes);
1316 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1317 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1318 (*i)->set_block_size (nframes);
1321 set_worst_io_latencies ();
1326 Session::set_default_fade (float steepness, float fade_msecs)
1329 nframes_t fade_frames;
1331 /* Don't allow fade of less 1 frame */
1333 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1340 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1344 default_fade_msecs = fade_msecs;
1345 default_fade_steepness = steepness;
1348 // jlc, WTF is this!
1349 Glib::RWLock::ReaderLock lm (route_lock);
1350 AudioRegion::set_default_fade (steepness, fade_frames);
1355 /* XXX have to do this at some point */
1356 /* foreach region using default fade, reset, then
1357 refill_all_diskstream_buffers ();
1362 struct RouteSorter {
1363 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1364 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1366 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1369 if (r1->fed_by.empty()) {
1370 if (r2->fed_by.empty()) {
1371 /* no ardour-based connections inbound to either route. just use signal order */
1372 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1374 /* r2 has connections, r1 does not; run r1 early */
1378 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1385 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1387 shared_ptr<Route> r2;
1389 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1390 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1394 /* make a copy of the existing list of routes that feed r1 */
1396 set<shared_ptr<Route> > existing = r1->fed_by;
1398 /* for each route that feeds r1, recurse, marking it as feeding
1402 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1405 /* r2 is a route that feeds r1 which somehow feeds base. mark
1406 base as being fed by r2
1409 rbase->fed_by.insert (r2);
1413 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1417 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1421 /* now recurse, so that we can mark base as being fed by
1422 all routes that feed r2
1425 trace_terminal (r2, rbase);
1432 Session::resort_routes ()
1434 /* don't do anything here with signals emitted
1435 by Routes while we are being destroyed.
1438 if (_state_of_the_state & Deletion) {
1445 RCUWriter<RouteList> writer (routes);
1446 shared_ptr<RouteList> r = writer.get_copy ();
1447 resort_routes_using (r);
1448 /* writer goes out of scope and forces update */
1453 Session::resort_routes_using (shared_ptr<RouteList> r)
1455 RouteList::iterator i, j;
1457 for (i = r->begin(); i != r->end(); ++i) {
1459 (*i)->fed_by.clear ();
1461 for (j = r->begin(); j != r->end(); ++j) {
1463 /* although routes can feed themselves, it will
1464 cause an endless recursive descent if we
1465 detect it. so don't bother checking for
1473 if ((*j)->feeds (*i)) {
1474 (*i)->fed_by.insert (*j);
1479 for (i = r->begin(); i != r->end(); ++i) {
1480 trace_terminal (*i, *i);
1487 cerr << "finished route resort\n";
1489 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1490 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1497 list<boost::shared_ptr<MidiTrack> >
1498 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1500 char track_name[32];
1501 uint32_t track_id = 0;
1504 RouteList new_routes;
1505 list<boost::shared_ptr<MidiTrack> > ret;
1506 //uint32_t control_id;
1508 // FIXME: need physical I/O and autoconnect stuff for MIDI
1510 /* count existing midi tracks */
1513 shared_ptr<RouteList> r = routes.reader ();
1515 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1516 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1517 if (!(*i)->is_hidden()) {
1519 //channels_used += (*i)->n_inputs().n_midi();
1525 vector<string> physinputs;
1526 vector<string> physoutputs;
1528 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1529 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1531 // control_id = ntracks() + nbusses();
1535 /* check for duplicate route names, since we might have pre-existing
1536 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1537 save, close,restart,add new route - first named route is now
1545 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1547 if (route_by_name (track_name) == 0) {
1551 } while (track_id < (UINT_MAX-1));
1553 shared_ptr<MidiTrack> track;
1556 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1558 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1559 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1565 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1569 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1570 port = physinputs[(channels_used+x)%nphysical_in];
1573 if (port.length() && track->connect_input (track->input (x), port, this)) {
1579 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1583 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1584 port = physoutputs[(channels_used+x)%nphysical_out];
1585 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1587 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1591 if (port.length() && track->connect_output (track->output (x), port, this)) {
1596 channels_used += track->n_inputs ().n_midi();
1600 track->midi_diskstream()->non_realtime_input_change();
1602 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1603 //track->set_remote_control_id (control_id);
1605 new_routes.push_back (track);
1606 ret.push_back (track);
1609 catch (failed_constructor &err) {
1610 error << _("Session: could not create new midi track.") << endmsg;
1613 /* we need to get rid of this, since the track failed to be created */
1614 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1617 RCUWriter<DiskstreamList> writer (diskstreams);
1618 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1619 ds->remove (track->midi_diskstream());
1626 catch (AudioEngine::PortRegistrationFailure& pfe) {
1628 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;
1631 /* we need to get rid of this, since the track failed to be created */
1632 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1635 RCUWriter<DiskstreamList> writer (diskstreams);
1636 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1637 ds->remove (track->midi_diskstream());
1648 if (!new_routes.empty()) {
1649 add_routes (new_routes, false);
1650 save_state (_current_snapshot_name);
1656 list<boost::shared_ptr<AudioTrack> >
1657 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1659 char track_name[32];
1660 uint32_t track_id = 0;
1662 uint32_t channels_used = 0;
1664 RouteList new_routes;
1665 list<boost::shared_ptr<AudioTrack> > ret;
1666 uint32_t control_id;
1668 /* count existing audio tracks */
1671 shared_ptr<RouteList> r = routes.reader ();
1673 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1674 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1675 if (!(*i)->is_hidden()) {
1677 channels_used += (*i)->n_inputs().n_audio();
1683 vector<string> physinputs;
1684 vector<string> physoutputs;
1686 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1687 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1689 control_id = ntracks() + nbusses() + 1;
1693 /* check for duplicate route names, since we might have pre-existing
1694 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1695 save, close,restart,add new route - first named route is now
1703 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1705 if (route_by_name (track_name) == 0) {
1709 } while (track_id < (UINT_MAX-1));
1711 shared_ptr<AudioTrack> track;
1714 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1716 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1717 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1718 input_channels, output_channels)
1723 if (!physinputs.empty()) {
1724 uint32_t nphysical_in = physinputs.size();
1726 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1730 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1731 port = physinputs[(channels_used+x)%nphysical_in];
1734 if (port.length() && track->connect_input (track->input (x), port, this)) {
1740 if (!physoutputs.empty()) {
1741 uint32_t nphysical_out = physoutputs.size();
1743 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1746 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1747 port = physoutputs[(channels_used+x)%nphysical_out];
1748 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1749 if (_master_out && _master_out->n_inputs().n_audio() > 0) {
1750 port = _master_out->input (x % _master_out->n_inputs().n_audio())->name();
1754 if (port.length() && track->connect_output (track->output (x), port, this)) {
1760 channels_used += track->n_inputs ().n_audio();
1762 track->audio_diskstream()->non_realtime_input_change();
1764 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1765 track->set_remote_control_id (control_id);
1768 new_routes.push_back (track);
1769 ret.push_back (track);
1772 catch (failed_constructor &err) {
1773 error << _("Session: could not create new audio track.") << endmsg;
1776 /* we need to get rid of this, since the track failed to be created */
1777 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1780 RCUWriter<DiskstreamList> writer (diskstreams);
1781 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1782 ds->remove (track->audio_diskstream());
1789 catch (AudioEngine::PortRegistrationFailure& pfe) {
1791 error << pfe.what() << endmsg;
1794 /* we need to get rid of this, since the track failed to be created */
1795 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1798 RCUWriter<DiskstreamList> writer (diskstreams);
1799 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1800 ds->remove (track->audio_diskstream());
1811 if (!new_routes.empty()) {
1812 add_routes (new_routes, true);
1819 Session::set_remote_control_ids ()
1821 RemoteModel m = Config->get_remote_model();
1823 shared_ptr<RouteList> r = routes.reader ();
1825 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1826 if ( MixerOrdered == m) {
1827 long order = (*i)->order_key(N_("signal"));
1828 (*i)->set_remote_control_id( order+1 );
1829 } else if ( EditorOrdered == m) {
1830 long order = (*i)->order_key(N_("editor"));
1831 (*i)->set_remote_control_id( order+1 );
1832 } else if ( UserOrdered == m) {
1833 //do nothing ... only changes to remote id's are initiated by user
1840 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1843 uint32_t bus_id = 1;
1845 uint32_t channels_used = 0;
1848 uint32_t control_id;
1850 /* count existing audio busses */
1853 shared_ptr<RouteList> r = routes.reader ();
1855 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1856 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1858 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1861 channels_used += (*i)->n_inputs().n_audio();
1867 vector<string> physinputs;
1868 vector<string> physoutputs;
1870 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1871 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1873 n_physical_audio_outputs = physoutputs.size();
1874 n_physical_audio_inputs = physinputs.size();
1876 control_id = ntracks() + nbusses() + 1;
1881 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1885 if (route_by_name (bus_name) == 0) {
1889 } while (bus_id < (UINT_MAX-1));
1892 shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
1894 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1895 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1896 input_channels, output_channels)
1904 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1908 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1909 port = physinputs[((n+x)%n_physical_audio_inputs)];
1912 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1918 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1921 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1922 port = physoutputs[((n+x)%n_physical_outputs)];
1923 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1925 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1929 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1934 channels_used += bus->n_inputs ().n_audio();
1936 bus->set_remote_control_id (control_id);
1939 ret.push_back (bus);
1943 catch (failed_constructor &err) {
1944 error << _("Session: could not create new audio route.") << endmsg;
1948 catch (AudioEngine::PortRegistrationFailure& pfe) {
1949 error << pfe.what() << endmsg;
1959 add_routes (ret, true);
1967 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1971 uint32_t control_id;
1974 if (!tree.read (template_path.c_str())) {
1978 XMLNode* node = tree.root();
1980 control_id = ntracks() + nbusses() + 1;
1984 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
1986 std::string node_name = IO::name_from_state (*node_copy.children().front());
1988 if (route_by_name (node_name) != 0) {
1990 /* generate a new name by adding a number to the end of the template name */
1992 uint32_t number = 1;
1995 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
1999 if (route_by_name (name) == 0) {
2003 } while (number < UINT_MAX);
2005 if (number == UINT_MAX) {
2006 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2010 IO::set_name_in_state (*node_copy.children().front(), name);
2013 Track::zero_diskstream_id_in_xml (node_copy);
2016 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2019 error << _("Session: cannot create track/bus from template description") << endmsg;
2023 if (boost::dynamic_pointer_cast<Track>(route)) {
2024 /* force input/output change signals so that the new diskstream
2025 picks up the configuration of the route. During session
2026 loading this normally happens in a different way.
2028 route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2029 route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2032 route->set_remote_control_id (control_id);
2035 ret.push_back (route);
2038 catch (failed_constructor &err) {
2039 error << _("Session: could not create new route from template") << endmsg;
2043 catch (AudioEngine::PortRegistrationFailure& pfe) {
2044 error << pfe.what() << endmsg;
2053 add_routes (ret, true);
2060 Session::add_routes (RouteList& new_routes, bool save)
2063 RCUWriter<RouteList> writer (routes);
2064 shared_ptr<RouteList> r = writer.get_copy ();
2065 r->insert (r->end(), new_routes.begin(), new_routes.end());
2066 resort_routes_using (r);
2069 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2071 boost::weak_ptr<Route> wpr (*x);
2073 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2074 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2075 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2076 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2078 if ((*x)->is_master()) {
2082 if ((*x)->is_control()) {
2083 _control_out = (*x);
2087 if (_control_out && IO::connecting_legal) {
2089 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2090 (*x)->listen_via (_control_out, "control");
2097 save_state (_current_snapshot_name);
2100 RouteAdded (new_routes); /* EMIT SIGNAL */
2104 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2106 /* need to do this in case we're rolling at the time, to prevent false underruns */
2107 dstream->do_refill_with_alloc ();
2109 dstream->set_block_size (current_block_size);
2112 RCUWriter<DiskstreamList> writer (diskstreams);
2113 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2114 ds->push_back (dstream);
2115 /* writer goes out of scope, copies ds back to main */
2118 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2119 /* this will connect to future changes, and check the current length */
2120 diskstream_playlist_changed (dstream);
2122 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2124 dstream->prepare ();
2129 Session::remove_route (shared_ptr<Route> route)
2132 RCUWriter<RouteList> writer (routes);
2133 shared_ptr<RouteList> rs = writer.get_copy ();
2137 /* deleting the master out seems like a dumb
2138 idea, but its more of a UI policy issue
2142 if (route == _master_out) {
2143 _master_out = shared_ptr<Route> ();
2146 if (route == _control_out) {
2147 /* cancel control outs for all routes */
2149 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2150 (*r)->drop_listen (_control_out);
2153 _control_out = shared_ptr<Route> ();
2156 update_route_solo_state ();
2158 /* writer goes out of scope, forces route list update */
2161 boost::shared_ptr<Track> t;
2162 boost::shared_ptr<Diskstream> ds;
2164 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2165 ds = t->diskstream();
2171 RCUWriter<DiskstreamList> dsl (diskstreams);
2172 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2177 find_current_end ();
2179 // We need to disconnect the routes inputs and outputs
2181 route->disconnect_inputs (0);
2182 route->disconnect_outputs (0);
2184 update_latency_compensation (false, false);
2187 /* get rid of it from the dead wood collection in the route list manager */
2189 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2193 /* try to cause everyone to drop their references */
2195 route->drop_references ();
2197 sync_order_keys (N_("session"));
2199 /* save the new state of the world */
2201 if (save_state (_current_snapshot_name)) {
2202 save_history (_current_snapshot_name);
2207 Session::route_mute_changed (void* src)
2213 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2215 if (solo_update_disabled) {
2221 boost::shared_ptr<Route> route = wpr.lock ();
2224 /* should not happen */
2225 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2229 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2231 shared_ptr<RouteList> r = routes.reader ();
2233 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2235 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2239 /* don't mess with busses */
2241 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
2247 /* don't mess with tracks */
2249 if (boost::dynamic_pointer_cast<Track>(*i) != 0) {
2254 if ((*i) != route &&
2255 ((*i)->mix_group () == 0 ||
2256 (*i)->mix_group () != route->mix_group () ||
2257 !route->mix_group ()->is_active())) {
2259 if ((*i)->soloed()) {
2261 /* if its already soloed, and solo latching is enabled,
2262 then leave it as it is.
2265 if (Config->get_solo_latched()) {
2272 solo_update_disabled = true;
2273 (*i)->set_solo (false, src);
2274 solo_update_disabled = false;
2278 bool something_soloed = false;
2279 bool same_thing_soloed = false;
2280 bool signal = false;
2282 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2283 if ((*i)->soloed()) {
2284 something_soloed = true;
2285 if (boost::dynamic_pointer_cast<Track>(*i)) {
2287 same_thing_soloed = true;
2292 same_thing_soloed = true;
2300 if (something_soloed != currently_soloing) {
2302 currently_soloing = something_soloed;
2305 modify_solo_mute (is_track, same_thing_soloed);
2308 SoloActive (currently_soloing); /* EMIT SIGNAL */
2311 SoloChanged (); /* EMIT SIGNAL */
2317 Session::update_route_solo_state ()
2320 bool is_track = false;
2321 bool signal = false;
2323 /* this is where we actually implement solo by changing
2324 the solo mute setting of each track.
2327 shared_ptr<RouteList> r = routes.reader ();
2329 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2330 if ((*i)->soloed()) {
2332 if (boost::dynamic_pointer_cast<Track>(*i)) {
2339 if (mute != currently_soloing) {
2341 currently_soloing = mute;
2344 if (!is_track && !mute) {
2346 /* nothing is soloed */
2348 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2349 (*i)->set_solo_mute (false);
2359 modify_solo_mute (is_track, mute);
2362 SoloActive (currently_soloing);
2367 Session::modify_solo_mute (bool is_track, bool mute)
2369 shared_ptr<RouteList> r = routes.reader ();
2371 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2375 /* only alter track solo mute */
2377 if (boost::dynamic_pointer_cast<Track>(*i)) {
2378 if ((*i)->soloed()) {
2379 (*i)->set_solo_mute (!mute);
2381 (*i)->set_solo_mute (mute);
2387 /* only alter bus solo mute */
2389 if (!boost::dynamic_pointer_cast<Track>(*i)) {
2391 if ((*i)->soloed()) {
2393 (*i)->set_solo_mute (false);
2397 /* don't mute master or control outs
2398 in response to another bus solo
2401 if ((*i) != _master_out &&
2402 (*i) != _control_out) {
2403 (*i)->set_solo_mute (mute);
2414 Session::catch_up_on_solo ()
2416 /* this is called after set_state() to catch the full solo
2417 state, which can't be correctly determined on a per-route
2418 basis, but needs the global overview that only the session
2421 update_route_solo_state();
2425 Session::catch_up_on_solo_mute_override ()
2427 if (Config->get_solo_model() != InverseMute) {
2431 /* this is called whenever the param solo-mute-override is
2434 shared_ptr<RouteList> r = routes.reader ();
2436 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2437 (*i)->catch_up_on_solo_mute_override ();
2442 Session::route_by_name (string name)
2444 shared_ptr<RouteList> r = routes.reader ();
2446 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2447 if ((*i)->name() == name) {
2452 return shared_ptr<Route> ((Route*) 0);
2456 Session::route_by_id (PBD::ID id)
2458 shared_ptr<RouteList> r = routes.reader ();
2460 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2461 if ((*i)->id() == id) {
2466 return shared_ptr<Route> ((Route*) 0);
2470 Session::route_by_remote_id (uint32_t id)
2472 shared_ptr<RouteList> r = routes.reader ();
2474 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2475 if ((*i)->remote_control_id() == id) {
2480 return shared_ptr<Route> ((Route*) 0);
2484 Session::find_current_end ()
2486 if (_state_of_the_state & Loading) {
2490 nframes_t max = get_maximum_extent ();
2492 if (max > end_location->end()) {
2493 end_location->set_end (max);
2495 DurationChanged(); /* EMIT SIGNAL */
2500 Session::get_maximum_extent () const
2505 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2507 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2508 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2510 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2511 if ((me = pl->get_maximum_extent()) > max) {
2519 boost::shared_ptr<Diskstream>
2520 Session::diskstream_by_name (string name)
2522 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2524 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2525 if ((*i)->name() == name) {
2530 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2533 boost::shared_ptr<Diskstream>
2534 Session::diskstream_by_id (const PBD::ID& id)
2536 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2538 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2539 if ((*i)->id() == id) {
2544 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2547 /* Region management */
2550 Session::new_region_name (string old)
2552 string::size_type last_period;
2554 string::size_type len = old.length() + 64;
2557 if ((last_period = old.find_last_of ('.')) == string::npos) {
2559 /* no period present - add one explicitly */
2562 last_period = old.length() - 1;
2567 number = atoi (old.substr (last_period+1).c_str());
2571 while (number < (UINT_MAX-1)) {
2573 RegionList::const_iterator i;
2578 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2581 for (i = regions.begin(); i != regions.end(); ++i) {
2582 if (i->second->name() == sbuf) {
2587 if (i == regions.end()) {
2592 if (number != (UINT_MAX-1)) {
2596 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2601 Session::region_name (string& result, string base, bool newlevel)
2606 if (base.find("/") != string::npos) {
2607 base = base.substr(base.find_last_of("/") + 1);
2612 Glib::Mutex::Lock lm (region_lock);
2614 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2623 string::size_type pos;
2625 pos = base.find_last_of ('.');
2627 /* pos may be npos, but then we just use entire base */
2629 subbase = base.substr (0, pos);
2634 Glib::Mutex::Lock lm (region_lock);
2636 map<string,uint32_t>::iterator x;
2640 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2642 region_name_map[subbase] = 1;
2645 snprintf (buf, sizeof (buf), ".%d", x->second);
2656 Session::add_region (boost::shared_ptr<Region> region)
2658 vector<boost::shared_ptr<Region> > v;
2659 v.push_back (region);
2664 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2669 Glib::Mutex::Lock lm (region_lock);
2671 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2673 boost::shared_ptr<Region> region = *ii;
2677 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2681 RegionList::iterator x;
2683 for (x = regions.begin(); x != regions.end(); ++x) {
2685 if (region->region_list_equivalent (x->second)) {
2690 if (x == regions.end()) {
2692 pair<RegionList::key_type,RegionList::mapped_type> entry;
2694 entry.first = region->id();
2695 entry.second = region;
2697 pair<RegionList::iterator,bool> x = regions.insert (entry);
2709 /* mark dirty because something has changed even if we didn't
2710 add the region to the region list.
2717 vector<boost::weak_ptr<Region> > v;
2718 boost::shared_ptr<Region> first_r;
2720 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2722 boost::shared_ptr<Region> region = *ii;
2726 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2729 v.push_back (region);
2736 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2737 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2739 update_region_name_map (region);
2743 RegionsAdded (v); /* EMIT SIGNAL */
2749 Session::update_region_name_map (boost::shared_ptr<Region> region)
2751 string::size_type last_period = region->name().find_last_of ('.');
2753 if (last_period != string::npos && last_period < region->name().length() - 1) {
2755 string base = region->name().substr (0, last_period);
2756 string number = region->name().substr (last_period+1);
2757 map<string,uint32_t>::iterator x;
2759 /* note that if there is no number, we get zero from atoi,
2763 region_name_map[base] = atoi (number);
2768 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2770 boost::shared_ptr<Region> region (weak_region.lock ());
2776 if (what_changed & Region::HiddenChanged) {
2777 /* relay hidden changes */
2778 RegionHiddenChange (region);
2781 if (what_changed & NameChanged) {
2782 update_region_name_map (region);
2787 Session::remove_region (boost::weak_ptr<Region> weak_region)
2789 RegionList::iterator i;
2790 boost::shared_ptr<Region> region (weak_region.lock ());
2796 bool removed = false;
2799 Glib::Mutex::Lock lm (region_lock);
2801 if ((i = regions.find (region->id())) != regions.end()) {
2807 /* mark dirty because something has changed even if we didn't
2808 remove the region from the region list.
2814 RegionRemoved(region); /* EMIT SIGNAL */
2818 boost::shared_ptr<Region>
2819 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2821 RegionList::iterator i;
2822 boost::shared_ptr<Region> region;
2824 Glib::Mutex::Lock lm (region_lock);
2826 for (i = regions.begin(); i != regions.end(); ++i) {
2830 if (region->whole_file()) {
2832 if (child->source_equivalent (region)) {
2838 return boost::shared_ptr<Region> ();
2842 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2844 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2845 (*i)->get_region_list_equivalent_regions (region, result);
2849 Session::destroy_region (boost::shared_ptr<Region> region)
2851 vector<boost::shared_ptr<Source> > srcs;
2854 if (region->playlist()) {
2855 region->playlist()->destroy_region (region);
2858 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2859 srcs.push_back (region->source (n));
2863 region->drop_references ();
2865 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2867 (*i)->mark_for_remove ();
2868 (*i)->drop_references ();
2870 cerr << "source was not used by any playlist\n";
2877 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2879 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2880 destroy_region (*i);
2886 Session::remove_last_capture ()
2888 list<boost::shared_ptr<Region> > r;
2890 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2892 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2893 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2896 r.insert (r.end(), l.begin(), l.end());
2901 destroy_regions (r);
2903 save_state (_current_snapshot_name);
2909 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2915 /* Source Management */
2918 Session::add_source (boost::shared_ptr<Source> source)
2920 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2921 pair<SourceMap::iterator,bool> result;
2923 entry.first = source->id();
2924 entry.second = source;
2927 Glib::Mutex::Lock lm (source_lock);
2928 result = sources.insert (entry);
2931 if (result.second) {
2932 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2936 boost::shared_ptr<AudioFileSource> afs;
2938 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2939 if (Config->get_auto_analyse_audio()) {
2940 Analyser::queue_source_for_analysis (source, false);
2946 Session::remove_source (boost::weak_ptr<Source> src)
2948 SourceMap::iterator i;
2949 boost::shared_ptr<Source> source = src.lock();
2956 Glib::Mutex::Lock lm (source_lock);
2958 if ((i = sources.find (source->id())) != sources.end()) {
2963 if (!_state_of_the_state & InCleanup) {
2965 /* save state so we don't end up with a session file
2966 referring to non-existent sources.
2969 save_state (_current_snapshot_name);
2973 boost::shared_ptr<Source>
2974 Session::source_by_id (const PBD::ID& id)
2976 Glib::Mutex::Lock lm (source_lock);
2977 SourceMap::iterator i;
2978 boost::shared_ptr<Source> source;
2980 if ((i = sources.find (id)) != sources.end()) {
2987 boost::shared_ptr<Source>
2988 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
2990 Glib::Mutex::Lock lm (source_lock);
2992 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2993 cerr << "comparing " << path << " with " << i->second->name() << endl;
2994 boost::shared_ptr<AudioFileSource> afs
2995 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
2997 if (afs && afs->path() == path && chn == afs->channel()) {
3001 return boost::shared_ptr<Source>();
3006 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3009 string old_basename = PBD::basename_nosuffix (oldname);
3010 string new_legalized = legalize_for_path (newname);
3012 /* note: we know (or assume) the old path is already valid */
3016 /* destructive file sources have a name of the form:
3018 /path/to/Tnnnn-NAME(%[LR])?.wav
3020 the task here is to replace NAME with the new name.
3023 /* find last slash */
3027 string::size_type slash;
3028 string::size_type dash;
3030 if ((slash = path.find_last_of ('/')) == string::npos) {
3034 dir = path.substr (0, slash+1);
3036 /* '-' is not a legal character for the NAME part of the path */
3038 if ((dash = path.find_last_of ('-')) == string::npos) {
3042 prefix = path.substr (slash+1, dash-(slash+1));
3047 path += new_legalized;
3048 path += ".wav"; /* XXX gag me with a spoon */
3052 /* non-destructive file sources have a name of the form:
3054 /path/to/NAME-nnnnn(%[LR])?.ext
3056 the task here is to replace NAME with the new name.
3061 string::size_type slash;
3062 string::size_type dash;
3063 string::size_type postfix;
3065 /* find last slash */
3067 if ((slash = path.find_last_of ('/')) == string::npos) {
3071 dir = path.substr (0, slash+1);
3073 /* '-' is not a legal character for the NAME part of the path */
3075 if ((dash = path.find_last_of ('-')) == string::npos) {
3079 suffix = path.substr (dash+1);
3081 // Suffix is now everything after the dash. Now we need to eliminate
3082 // the nnnnn part, which is done by either finding a '%' or a '.'
3084 postfix = suffix.find_last_of ("%");
3085 if (postfix == string::npos) {
3086 postfix = suffix.find_last_of ('.');
3089 if (postfix != string::npos) {
3090 suffix = suffix.substr (postfix);
3092 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3096 const uint32_t limit = 10000;
3097 char buf[PATH_MAX+1];
3099 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3101 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3103 if (access (buf, F_OK) != 0) {
3111 error << "FATAL ERROR! Could not find a " << endl;
3119 /** Return the full path (in some session directory) for a new embedded source.
3120 * \a name must be a session-unique name that does not contain slashes
3121 * (e.g. as returned by new_*_source_name)
3124 Session::new_source_path_from_name (DataType type, const string& name)
3126 assert(name.find("/") == string::npos);
3128 SessionDirectory sdir(get_best_session_directory_for_new_source());
3131 if (type == DataType::AUDIO) {
3132 p = sdir.sound_path();
3133 } else if (type == DataType::MIDI) {
3134 p = sdir.midi_path();
3136 error << "Unknown source type, unable to create file path" << endmsg;
3141 return p.to_string();
3145 Session::peak_path (Glib::ustring base) const
3147 sys::path peakfile_path(_session_dir->peak_path());
3148 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3149 return peakfile_path.to_string();
3152 /** Return a unique name based on \a base for a new internal audio source */
3154 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3158 char buf[PATH_MAX+1];
3159 const uint32_t limit = 10000;
3163 legalized = legalize_for_path (base);
3165 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3166 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3168 vector<space_and_path>::iterator i;
3169 uint32_t existing = 0;
3171 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3173 SessionDirectory sdir((*i).path);
3175 spath = sdir.sound_path().to_string();
3180 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3181 spath.c_str(), cnt, legalized.c_str());
3182 } else if (nchan == 2) {
3184 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3185 spath.c_str(), cnt, legalized.c_str());
3187 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3188 spath.c_str(), cnt, legalized.c_str());
3190 } else if (nchan < 26) {
3191 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3192 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3194 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3195 spath.c_str(), cnt, legalized.c_str());
3204 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3205 } else if (nchan == 2) {
3207 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3209 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3211 } else if (nchan < 26) {
3212 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3214 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3218 if (sys::exists(buf)) {
3224 if (existing == 0) {
3229 error << string_compose(
3230 _("There are already %1 recordings for %2, which I consider too many."),
3231 limit, base) << endmsg;
3233 throw failed_constructor();
3237 return Glib::path_get_basename(buf);
3240 /** Create a new embedded audio source */
3241 boost::shared_ptr<AudioFileSource>
3242 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3244 const size_t n_chans = ds.n_channels().n_audio();
3245 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3246 const string path = new_source_path_from_name(DataType::AUDIO, name);
3247 return boost::dynamic_pointer_cast<AudioFileSource> (
3248 SourceFactory::createWritable (
3249 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3252 /** Return a unique name based on \a base for a new internal MIDI source */
3254 Session::new_midi_source_name (const string& base)
3257 char buf[PATH_MAX+1];
3258 const uint32_t limit = 10000;
3262 legalized = legalize_for_path (base);
3264 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3265 for (cnt = 1; cnt <= limit; ++cnt) {
3267 vector<space_and_path>::iterator i;
3268 uint32_t existing = 0;
3270 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3272 SessionDirectory sdir((*i).path);
3274 sys::path p = sdir.midi_path();
3277 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3279 if (sys::exists (buf)) {
3284 if (existing == 0) {
3289 error << string_compose(
3290 _("There are already %1 recordings for %2, which I consider too many."),
3291 limit, base) << endmsg;
3293 throw failed_constructor();
3297 return Glib::path_get_basename(buf);
3301 /** Create a new embedded MIDI source */
3302 boost::shared_ptr<MidiSource>
3303 Session::create_midi_source_for_session (MidiDiskstream& ds)
3305 const string name = new_midi_source_name (ds.name());
3306 const string path = new_source_path_from_name (DataType::MIDI, name);
3308 return boost::dynamic_pointer_cast<SMFSource> (
3309 SourceFactory::createWritable (
3310 DataType::MIDI, *this, path, true, false, frame_rate()));
3314 /* Playlist management */
3316 boost::shared_ptr<Playlist>
3317 Session::playlist_by_name (string name)
3319 Glib::Mutex::Lock lm (playlist_lock);
3320 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3321 if ((*i)->name() == name) {
3325 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3326 if ((*i)->name() == name) {
3331 return boost::shared_ptr<Playlist>();
3335 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3337 Glib::Mutex::Lock lm (playlist_lock);
3338 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3339 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3340 list.push_back (*i);
3343 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3344 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3345 list.push_back (*i);
3351 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3353 if (playlist->hidden()) {
3358 Glib::Mutex::Lock lm (playlist_lock);
3359 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3360 playlists.insert (playlists.begin(), playlist);
3361 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3362 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3367 playlist->release();
3372 PlaylistAdded (playlist); /* EMIT SIGNAL */
3376 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3379 Glib::Mutex::Lock lm (playlist_lock);
3380 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3383 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3390 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3392 boost::shared_ptr<Playlist> pl(wpl.lock());
3398 PlaylistList::iterator x;
3401 /* its not supposed to be visible */
3406 Glib::Mutex::Lock lm (playlist_lock);
3410 unused_playlists.insert (pl);
3412 if ((x = playlists.find (pl)) != playlists.end()) {
3413 playlists.erase (x);
3419 playlists.insert (pl);
3421 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3422 unused_playlists.erase (x);
3429 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3431 if (_state_of_the_state & Deletion) {
3435 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3442 Glib::Mutex::Lock lm (playlist_lock);
3444 PlaylistList::iterator i;
3446 i = find (playlists.begin(), playlists.end(), playlist);
3447 if (i != playlists.end()) {
3448 playlists.erase (i);
3451 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3452 if (i != unused_playlists.end()) {
3453 unused_playlists.erase (i);
3460 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3464 Session::set_audition (boost::shared_ptr<Region> r)
3466 pending_audition_region = r;
3467 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3468 schedule_butler_transport_work ();
3472 Session::audition_playlist ()
3474 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3475 ev->region.reset ();
3480 Session::non_realtime_set_audition ()
3482 if (!pending_audition_region) {
3483 auditioner->audition_current_playlist ();
3485 auditioner->audition_region (pending_audition_region);
3486 pending_audition_region.reset ();
3488 AuditionActive (true); /* EMIT SIGNAL */
3492 Session::audition_region (boost::shared_ptr<Region> r)
3494 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3500 Session::cancel_audition ()
3502 if (auditioner->active()) {
3503 auditioner->cancel_audition ();
3504 AuditionActive (false); /* EMIT SIGNAL */
3509 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3511 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3515 Session::remove_empty_sounds ()
3517 vector<string> audio_filenames;
3519 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3521 Glib::Mutex::Lock lm (source_lock);
3523 TapeFileMatcher tape_file_matcher;
3525 remove_if (audio_filenames.begin(), audio_filenames.end(),
3526 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3528 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3530 sys::path audio_file_path (_session_dir->sound_path());
3532 audio_file_path /= *i;
3534 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3538 sys::remove (audio_file_path);
3539 const string peakfile = peak_path (audio_file_path.to_string());
3540 sys::remove (peakfile);
3542 catch (const sys::filesystem_error& err)
3544 error << err.what() << endmsg;
3551 Session::is_auditioning () const
3553 /* can be called before we have an auditioner object */
3555 return auditioner->active();
3562 Session::set_all_solo (bool yn)
3564 shared_ptr<RouteList> r = routes.reader ();
3566 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3567 if (!(*i)->is_hidden()) {
3568 (*i)->set_solo (yn, this);
3576 Session::set_all_mute (bool yn)
3578 shared_ptr<RouteList> r = routes.reader ();
3580 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3581 if (!(*i)->is_hidden()) {
3582 (*i)->set_mute (yn, this);
3590 Session::n_diskstreams () const
3594 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3596 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3597 if (!(*i)->hidden()) {
3605 Session::graph_reordered ()
3607 /* don't do this stuff if we are setting up connections
3608 from a set_state() call or creating new tracks.
3611 if (_state_of_the_state & InitialConnecting) {
3615 /* every track/bus asked for this to be handled but it was deferred because
3616 we were connecting. do it now.
3619 request_input_change_handling ();
3623 /* force all diskstreams to update their capture offset values to
3624 reflect any changes in latencies within the graph.
3627 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3629 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3630 (*i)->set_capture_offset ();
3635 Session::record_disenable_all ()
3637 record_enable_change_all (false);
3641 Session::record_enable_all ()
3643 record_enable_change_all (true);
3647 Session::record_enable_change_all (bool yn)
3649 shared_ptr<RouteList> r = routes.reader ();
3651 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3652 boost::shared_ptr<Track> t;
3654 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3655 t->set_record_enable (yn, this);
3659 /* since we don't keep rec-enable state, don't mark session dirty */
3663 Session::add_processor (Processor* processor)
3667 PortInsert* port_insert;
3668 PluginInsert* plugin_insert;
3670 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3671 _port_inserts.insert (_port_inserts.begin(), port_insert);
3672 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3673 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3674 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3675 _sends.insert (_sends.begin(), send);
3676 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3677 _returns.insert (_returns.begin(), retrn);
3679 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3683 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3689 Session::remove_processor (Processor* processor)
3693 PortInsert* port_insert;
3694 PluginInsert* plugin_insert;
3696 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3697 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3698 if (x != _port_inserts.end()) {
3699 insert_bitset[port_insert->bit_slot()] = false;
3700 _port_inserts.erase (x);
3702 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3703 _plugin_inserts.remove (plugin_insert);
3704 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3705 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3706 if (x != _sends.end()) {
3707 send_bitset[send->bit_slot()] = false;
3710 } else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
3711 list<Return*>::iterator x = find (_returns.begin(), _returns.end(), retrn);
3712 if (x != _returns.end()) {
3713 return_bitset[send->bit_slot()] = false;
3717 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3725 Session::available_capture_duration ()
3727 float sample_bytes_on_disk = 4.0; // keep gcc happy
3729 switch (Config->get_native_file_data_format()) {
3731 sample_bytes_on_disk = 4.0;
3735 sample_bytes_on_disk = 3.0;
3739 sample_bytes_on_disk = 2.0;
3743 /* impossible, but keep some gcc versions happy */
3744 fatal << string_compose (_("programming error: %1"),
3745 X_("illegal native file data format"))
3750 double scale = 4096.0 / sample_bytes_on_disk;
3752 if (_total_free_4k_blocks * scale > (double) max_frames) {
3756 return (nframes_t) floor (_total_free_4k_blocks * scale);
3760 Session::add_bundle (shared_ptr<Bundle> bundle)
3763 RCUWriter<BundleList> writer (_bundles);
3764 boost::shared_ptr<BundleList> b = writer.get_copy ();
3765 b->push_back (bundle);
3768 BundleAdded (bundle); /* EMIT SIGNAL */
3774 Session::remove_bundle (shared_ptr<Bundle> bundle)
3776 bool removed = false;
3779 RCUWriter<BundleList> writer (_bundles);
3780 boost::shared_ptr<BundleList> b = writer.get_copy ();
3781 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3783 if (i != b->end()) {
3790 BundleRemoved (bundle); /* EMIT SIGNAL */
3797 Session::bundle_by_name (string name) const
3799 boost::shared_ptr<BundleList> b = _bundles.reader ();
3801 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3802 if ((*i)->name() == name) {
3807 return boost::shared_ptr<Bundle> ();
3811 Session::tempo_map_changed (Change ignored)
3815 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3816 (*i)->update_after_tempo_map_change ();
3819 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3820 (*i)->update_after_tempo_map_change ();
3826 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3827 * the given count with the current block size.
3830 Session::ensure_buffers (ChanCount howmany)
3832 if (current_block_size == 0) {
3833 return; // too early? (is this ok?)
3836 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3837 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3838 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3839 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3840 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3843 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3847 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3849 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3850 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3855 Session::next_insert_id ()
3857 /* this doesn't really loop forever. just think about it */
3860 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3861 if (!insert_bitset[n]) {
3862 insert_bitset[n] = true;
3868 /* none available, so resize and try again */
3870 insert_bitset.resize (insert_bitset.size() + 16, false);
3875 Session::next_send_id ()
3877 /* this doesn't really loop forever. just think about it */
3880 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3881 if (!send_bitset[n]) {
3882 send_bitset[n] = true;
3888 /* none available, so resize and try again */
3890 send_bitset.resize (send_bitset.size() + 16, false);
3895 Session::next_return_id ()
3897 /* this doesn't really loop forever. just think about it */
3900 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < return_bitset.size(); ++n) {
3901 if (!return_bitset[n]) {
3902 return_bitset[n] = true;
3908 /* none available, so resize and try again */
3910 return_bitset.resize (return_bitset.size() + 16, false);
3915 Session::mark_send_id (uint32_t id)
3917 if (id >= send_bitset.size()) {
3918 send_bitset.resize (id+16, false);
3920 if (send_bitset[id]) {
3921 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3923 send_bitset[id] = true;
3927 Session::mark_return_id (uint32_t id)
3929 if (id >= return_bitset.size()) {
3930 return_bitset.resize (id+16, false);
3932 if (return_bitset[id]) {
3933 warning << string_compose (_("return ID %1 appears to be in use already"), id) << endmsg;
3935 return_bitset[id] = true;
3939 Session::mark_insert_id (uint32_t id)
3941 if (id >= insert_bitset.size()) {
3942 insert_bitset.resize (id+16, false);
3944 if (insert_bitset[id]) {
3945 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3947 insert_bitset[id] = true;
3950 /* Named Selection management */
3953 Session::named_selection_by_name (string name)
3955 Glib::Mutex::Lock lm (named_selection_lock);
3956 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3957 if ((*i)->name == name) {
3965 Session::add_named_selection (NamedSelection* named_selection)
3968 Glib::Mutex::Lock lm (named_selection_lock);
3969 named_selections.insert (named_selections.begin(), named_selection);
3972 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3978 NamedSelectionAdded (); /* EMIT SIGNAL */
3982 Session::remove_named_selection (NamedSelection* named_selection)
3984 bool removed = false;
3987 Glib::Mutex::Lock lm (named_selection_lock);
3989 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3991 if (i != named_selections.end()) {
3993 named_selections.erase (i);
4000 NamedSelectionRemoved (); /* EMIT SIGNAL */
4005 Session::reset_native_file_format ()
4007 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
4009 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
4010 (*i)->reset_write_sources (false);
4015 Session::route_name_unique (string n) const
4017 shared_ptr<RouteList> r = routes.reader ();
4019 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4020 if ((*i)->name() == n) {
4029 Session::route_name_internal (string n) const
4031 if (auditioner && auditioner->name() == n) {
4035 if (_click_io && _click_io->name() == n) {
4043 Session::n_playlists () const
4045 Glib::Mutex::Lock lm (playlist_lock);
4046 return playlists.size();
4050 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4052 if (!force && howmany <= _npan_buffers) {
4056 if (_pan_automation_buffer) {
4058 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4059 delete [] _pan_automation_buffer[i];
4062 delete [] _pan_automation_buffer;
4065 _pan_automation_buffer = new pan_t*[howmany];
4067 for (uint32_t i = 0; i < howmany; ++i) {
4068 _pan_automation_buffer[i] = new pan_t[nframes];
4071 _npan_buffers = howmany;
4075 Session::freeze (InterThreadInfo& itt)
4077 shared_ptr<RouteList> r = routes.reader ();
4079 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4081 boost::shared_ptr<Track> t;
4083 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4084 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4094 boost::shared_ptr<Region>
4095 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4096 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
4097 InterThreadInfo& itt, bool enable_processing)
4099 boost::shared_ptr<Region> result;
4100 boost::shared_ptr<Playlist> playlist;
4101 boost::shared_ptr<AudioFileSource> fsource;
4103 char buf[PATH_MAX+1];
4104 ChanCount nchans(track.audio_diskstream()->n_channels());
4106 nframes_t this_chunk;
4109 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4110 const string sound_dir = sdir.sound_path().to_string();
4111 nframes_t len = end - start;
4114 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4115 end, start) << endmsg;
4119 // any bigger than this seems to cause stack overflows in called functions
4120 const nframes_t chunk_size = (128 * 1024)/4;
4122 // block all process callback handling
4124 block_processing ();
4126 /* call tree *MUST* hold route_lock */
4128 if ((playlist = track.diskstream()->playlist()) == 0) {
4132 /* external redirects will be a problem */
4134 if (track.has_external_redirects()) {
4138 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4140 for (x = 0; x < 99999; ++x) {
4141 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4142 if (access (buf, F_OK) != 0) {
4148 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4153 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4154 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4157 catch (failed_constructor& err) {
4158 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4162 srcs.push_back (fsource);
4165 /* XXX need to flush all redirects */
4170 /* create a set of reasonably-sized buffers */
4171 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4172 buffers.set_count(nchans);
4174 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4175 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4177 afs->prepare_for_peakfile_writes ();
4180 while (to_do && !itt.cancel) {
4182 this_chunk = min (to_do, chunk_size);
4184 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4189 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4190 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4193 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4199 start += this_chunk;
4200 to_do -= this_chunk;
4202 itt.progress = (float) (1.0 - ((double) to_do / len));
4211 xnow = localtime (&now);
4213 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4214 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4217 afs->update_header (position, *xnow, now);
4218 afs->flush_header ();
4222 /* construct a region to represent the bounced material */
4224 result = RegionFactory::create (srcs, 0,
4225 srcs.front()->length(srcs.front()->timeline_position()),
4226 region_name_from_path (srcs.front()->name(), true));
4231 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4232 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4235 afs->mark_for_remove ();
4238 (*src)->drop_references ();
4242 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4243 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4246 afs->done_with_peakfile_writes ();
4250 unblock_processing ();
4256 Session::get_silent_buffers (ChanCount count)
4258 assert(_silent_buffers->available() >= count);
4259 _silent_buffers->set_count(count);
4261 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4262 for (size_t i= 0; i < count.get(*t); ++i) {
4263 _silent_buffers->get(*t, i).clear();
4267 return *_silent_buffers;
4271 Session::get_scratch_buffers (ChanCount count)
4273 if (count != ChanCount::ZERO) {
4274 assert(_scratch_buffers->available() >= count);
4275 _scratch_buffers->set_count(count);
4277 _scratch_buffers->set_count (_scratch_buffers->available());
4280 return *_scratch_buffers;
4284 Session::get_mix_buffers (ChanCount count)
4286 assert(_mix_buffers->available() >= count);
4287 _mix_buffers->set_count(count);
4288 return *_mix_buffers;
4292 Session::ntracks () const
4295 shared_ptr<RouteList> r = routes.reader ();
4297 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4298 if (boost::dynamic_pointer_cast<Track> (*i)) {
4307 Session::nbusses () const
4310 shared_ptr<RouteList> r = routes.reader ();
4312 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4313 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4322 Session::add_automation_list(AutomationList *al)
4324 automation_lists[al->id()] = al;
4328 Session::compute_initial_length ()
4330 return _engine.frame_rate() * 60 * 5;
4334 Session::sync_order_keys (const char* base)
4336 if (!Config->get_sync_all_route_ordering()) {
4337 /* leave order keys as they are */
4341 boost::shared_ptr<RouteList> r = routes.reader ();
4343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4344 (*i)->sync_order_keys (base);
4347 Route::SyncOrderKeys (base); // EMIT SIGNAL
4351 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4353 Session::have_rec_enabled_diskstream () const
4355 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4358 /** Update the state of our rec-enabled diskstreams flag */
4360 Session::update_have_rec_enabled_diskstream ()
4362 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4363 DiskstreamList::iterator i = dsl->begin ();
4364 while (i != dsl->end () && (*i)->record_enabled () == false) {
4368 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4370 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4372 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4373 RecordStateChanged (); /* EMIT SIGNAL */