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/route_group.h"
76 #include "ardour/send.h"
77 #include "ardour/session.h"
78 #include "ardour/session_directory.h"
79 #include "ardour/session_directory.h"
80 #include "ardour/session_metadata.h"
81 #include "ardour/slave.h"
82 #include "ardour/smf_source.h"
83 #include "ardour/source_factory.h"
84 #include "ardour/tape_file_matcher.h"
85 #include "ardour/tempo.h"
86 #include "ardour/utils.h"
91 using namespace ARDOUR;
93 using boost::shared_ptr;
95 bool Session::_disable_all_loaded_plugins = false;
97 sigc::signal<void,std::string> Session::Dialog;
98 sigc::signal<int> Session::AskAboutPendingState;
99 sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch;
100 sigc::signal<void> Session::SendFeedback;
102 sigc::signal<void> Session::SMPTEOffsetChanged;
103 sigc::signal<void> Session::StartTimeChanged;
104 sigc::signal<void> Session::EndTimeChanged;
105 sigc::signal<void> Session::AutoBindingOn;
106 sigc::signal<void> Session::AutoBindingOff;
107 sigc::signal<void, std::string, std::string> Session::Exported;
109 Session::Session (AudioEngine &eng,
110 const string& fullpath,
111 const string& snapshot_name,
115 _requested_return_frame (-1),
116 _scratch_buffers(new BufferSet()),
117 _silent_buffers(new BufferSet()),
118 _mix_buffers(new BufferSet()),
120 _mmc_port (default_mmc_port),
121 _mtc_port (default_mtc_port),
122 _midi_port (default_midi_port),
123 _midi_clock_port (default_midi_clock_port),
124 _session_dir (new SessionDirectory(fullpath)),
125 pending_events (2048),
127 butler_mixdown_buffer (0),
128 butler_gain_buffer (0),
129 post_transport_work((PostTransportWork)0),
130 _send_smpte_update (false),
131 midi_thread (pthread_t (0)),
132 midi_requests (128), // the size of this should match the midi request pool size
133 diskstreams (new DiskstreamList),
134 routes (new RouteList),
135 auditioner ((Auditioner*) 0),
136 _total_free_4k_blocks (0),
137 _bundles (new BundleList),
138 _bundle_xml_node (0),
141 click_emphasis_data (0),
143 _metadata (new SessionMetadata()),
144 _have_rec_enabled_diskstream (false)
149 if (!eng.connected()) {
150 throw failed_constructor();
153 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl;
155 n_physical_outputs = _engine.n_physical_outputs(DataType::AUDIO);
156 n_physical_inputs = _engine.n_physical_inputs(DataType::AUDIO);
158 first_stage_init (fullpath, snapshot_name);
160 new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
163 if (create (new_session, mix_template, compute_initial_length())) {
165 throw failed_constructor ();
169 if (second_stage_init (new_session)) {
171 throw failed_constructor ();
174 store_recent_sessions(_name, _path);
176 bool was_dirty = dirty();
178 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
180 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
183 DirtyChanged (); /* EMIT SIGNAL */
187 Session::Session (AudioEngine &eng,
189 string snapshot_name,
190 AutoConnectOption input_ac,
191 AutoConnectOption output_ac,
192 uint32_t control_out_channels,
193 uint32_t master_out_channels,
194 uint32_t requested_physical_in,
195 uint32_t requested_physical_out,
196 nframes_t initial_length)
199 _requested_return_frame (-1),
200 _scratch_buffers(new BufferSet()),
201 _silent_buffers(new BufferSet()),
202 _mix_buffers(new BufferSet()),
204 _mmc_port (default_mmc_port),
205 _mtc_port (default_mtc_port),
206 _midi_port (default_midi_port),
207 _midi_clock_port (default_midi_clock_port),
208 _session_dir ( new SessionDirectory(fullpath)),
209 pending_events (2048),
211 butler_mixdown_buffer (0),
212 butler_gain_buffer (0),
213 post_transport_work((PostTransportWork)0),
214 _send_smpte_update (false),
215 midi_thread (pthread_t (0)),
217 diskstreams (new DiskstreamList),
218 routes (new RouteList),
219 auditioner ((Auditioner *) 0),
220 _total_free_4k_blocks (0),
221 _bundles (new BundleList),
222 _bundle_xml_node (0),
223 _click_io ((IO *) 0),
225 click_emphasis_data (0),
227 _metadata (new SessionMetadata()),
228 _have_rec_enabled_diskstream (false)
232 if (!eng.connected()) {
233 throw failed_constructor();
236 cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl;
238 n_physical_outputs = _engine.n_physical_outputs (DataType::AUDIO);
239 n_physical_inputs = _engine.n_physical_inputs (DataType::AUDIO);
241 if (n_physical_inputs) {
242 n_physical_inputs = max (requested_physical_in, n_physical_inputs);
245 if (n_physical_outputs) {
246 n_physical_outputs = max (requested_physical_out, n_physical_outputs);
249 first_stage_init (fullpath, snapshot_name);
251 new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
254 if (create (new_session, string(), initial_length)) {
256 throw failed_constructor ();
261 /* set up Master Out and Control Out if necessary */
266 if (control_out_channels) {
267 shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
268 r->set_remote_control_id (control_id++);
273 if (master_out_channels) {
274 shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
275 r->set_remote_control_id (control_id);
279 /* prohibit auto-connect to master, because there isn't one */
280 output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
284 add_routes (rl, false);
289 Config->set_input_auto_connect (input_ac);
290 Config->set_output_auto_connect (output_ac);
292 if (second_stage_init (new_session)) {
294 throw failed_constructor ();
297 store_recent_sessions (_name, _path);
299 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
301 Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
312 /* if we got to here, leaving pending capture state around
316 remove_pending_capture_state ();
318 _state_of_the_state = StateOfTheState (CannotSave|Deletion);
320 _engine.remove_session ();
322 GoingAway (); /* EMIT SIGNAL */
328 /* clear history so that no references to objects are held any more */
332 /* clear state tree so that no references to objects are held any more */
336 terminate_butler_thread ();
337 //terminate_midi_thread ();
339 if (click_data != default_click) {
340 delete [] click_data;
343 if (click_emphasis_data != default_click_emphasis) {
344 delete [] click_emphasis_data;
349 delete _scratch_buffers;
350 delete _silent_buffers;
353 AudioDiskstream::free_working_buffers();
355 Route::SyncOrderKeys.clear();
357 #undef TRACK_DESTRUCTION
358 #ifdef TRACK_DESTRUCTION
359 cerr << "delete named selections\n";
360 #endif /* TRACK_DESTRUCTION */
361 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) {
362 NamedSelectionList::iterator tmp;
371 #ifdef TRACK_DESTRUCTION
372 cerr << "delete playlists\n";
373 #endif /* TRACK_DESTRUCTION */
374 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) {
375 PlaylistList::iterator tmp;
380 (*i)->drop_references ();
385 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
386 PlaylistList::iterator tmp;
391 (*i)->drop_references ();
397 unused_playlists.clear ();
399 #ifdef TRACK_DESTRUCTION
400 cerr << "delete regions\n";
401 #endif /* TRACK_DESTRUCTION */
403 for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
404 RegionList::iterator tmp;
409 i->second->drop_references ();
416 #ifdef TRACK_DESTRUCTION
417 cerr << "delete routes\n";
418 #endif /* TRACK_DESTRUCTION */
420 RCUWriter<RouteList> writer (routes);
421 boost::shared_ptr<RouteList> r = writer.get_copy ();
422 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
423 (*i)->drop_references ();
426 /* writer goes out of scope and updates master */
431 #ifdef TRACK_DESTRUCTION
432 cerr << "delete diskstreams\n";
433 #endif /* TRACK_DESTRUCTION */
435 RCUWriter<DiskstreamList> dwriter (diskstreams);
436 boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
437 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
438 (*i)->drop_references ();
442 diskstreams.flush ();
444 #ifdef TRACK_DESTRUCTION
445 cerr << "delete audio sources\n";
446 #endif /* TRACK_DESTRUCTION */
447 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
448 SourceMap::iterator tmp;
453 i->second->drop_references ();
459 #ifdef TRACK_DESTRUCTION
460 cerr << "delete mix groups\n";
461 #endif /* TRACK_DESTRUCTION */
462 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) {
463 list<RouteGroup*>::iterator tmp;
473 #ifdef TRACK_DESTRUCTION
474 cerr << "delete edit groups\n";
475 #endif /* TRACK_DESTRUCTION */
476 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) {
477 list<RouteGroup*>::iterator tmp;
487 delete [] butler_mixdown_buffer;
488 delete [] butler_gain_buffer;
490 Crossfade::set_buffer_size (0);
496 Session::set_worst_io_latencies ()
498 _worst_output_latency = 0;
499 _worst_input_latency = 0;
501 if (!_engine.connected()) {
505 boost::shared_ptr<RouteList> r = routes.reader ();
507 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
508 _worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
509 _worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
514 Session::when_engine_running ()
516 string first_physical_output;
518 /* we don't want to run execute this again */
520 BootMessage (_("Set block size and sample rate"));
522 set_block_size (_engine.frames_per_cycle());
523 set_frame_rate (_engine.frame_rate());
525 BootMessage (_("Using configuration"));
527 Config->map_parameters (mem_fun (*this, &Session::config_changed));
529 /* every time we reconnect, recompute worst case output latencies */
531 _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
533 if (synced_to_jack()) {
534 _engine.transport_stop ();
537 if (Config->get_jack_time_master()) {
538 _engine.transport_locate (_transport_frame);
546 _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
548 if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
550 /* existing state for Click */
552 if (_click_io->set_state (*child->children().front()) == 0) {
554 _clicking = Config->get_clicking ();
558 error << _("could not setup Click I/O") << endmsg;
564 /* default state for Click: dual-mono to first 2 physical outputs */
566 for (int physport = 0; physport < 2; ++physport) {
567 string physical_output = _engine.get_nth_physical_output (DataType::AUDIO, physport);
569 if (physical_output.length()) {
570 if (_click_io->add_output_port (physical_output, this)) {
571 // relax, even though its an error
576 if (_click_io->n_outputs () > ChanCount::ZERO) {
577 _clicking = Config->get_clicking ();
582 catch (failed_constructor& err) {
583 error << _("cannot setup Click I/O") << endmsg;
586 BootMessage (_("Compute I/O Latencies"));
588 set_worst_io_latencies ();
591 // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
594 BootMessage (_("Set up standard connections"));
596 /* Create a set of Bundle objects that map
597 to the physical I/O currently available. We create both
598 mono and stereo bundles, so that the common cases of mono
599 and stereo tracks get bundles to put in their mixer strip
600 in / out menus. There may be a nicer way of achieving that;
601 it doesn't really scale that well to higher channel counts */
603 for (uint32_t np = 0; np < n_physical_outputs; ++np) {
605 snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
607 shared_ptr<Bundle> c (new Bundle (buf, true));
608 c->add_channel (_("mono"));
609 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
614 for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
615 if (np + 1 < n_physical_outputs) {
617 snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
618 shared_ptr<Bundle> c (new Bundle (buf, true));
619 c->add_channel (_("L"));
620 c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
621 c->add_channel (_("R"));
622 c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
628 for (uint32_t np = 0; np < n_physical_inputs; ++np) {
630 snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
632 shared_ptr<Bundle> c (new Bundle (buf, false));
633 c->add_channel (_("mono"));
634 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
639 for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
640 if (np + 1 < n_physical_inputs) {
642 snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
644 shared_ptr<Bundle> c (new Bundle (buf, false));
645 c->add_channel (_("L"));
646 c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
647 c->add_channel (_("R"));
648 c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
656 /* create master/control ports */
661 /* force the master to ignore any later call to this */
663 if (_master_out->pending_state_node) {
664 _master_out->ports_became_legal();
667 /* no panner resets till we are through */
669 _master_out->defer_pan_reset ();
671 while (_master_out->n_inputs().n_audio()
672 < _master_out->input_maximum().n_audio()) {
673 if (_master_out->add_input_port ("", this, DataType::AUDIO)) {
674 error << _("cannot setup master inputs")
680 while (_master_out->n_outputs().n_audio()
681 < _master_out->output_maximum().n_audio()) {
682 if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) {
683 error << _("cannot setup master outputs")
690 _master_out->allow_pan_reset ();
695 BootMessage (_("Setup signal flow and plugins"));
699 /* catch up on send+insert cnts */
701 BootMessage (_("Catch up with send/insert state"));
705 for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) {
708 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
709 if (id > insert_cnt) {
717 for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) {
720 if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) {
728 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
730 /* hook us up to the engine */
732 BootMessage (_("Connect to engine"));
734 _engine.set_session (this);
738 Session::hookup_io ()
740 /* stop graph reordering notifications from
741 causing resorts, etc.
744 _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting);
747 if (auditioner == 0) {
749 /* we delay creating the auditioner till now because
750 it makes its own connections to ports.
751 the engine has to be running for this to work.
755 auditioner.reset (new Auditioner (*this));
758 catch (failed_constructor& err) {
759 warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg;
763 /* Tell all IO objects to create their ports */
769 vector<string> cports;
771 while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) {
772 if (_control_out->add_input_port ("", this)) {
773 error << _("cannot setup control inputs")
779 while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) {
780 if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) {
781 error << _("cannot set up master outputs")
789 uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO);
791 for (n = 0; n < ni; ++n) {
792 cports.push_back (_control_out->input(n)->name());
795 boost::shared_ptr<RouteList> r = routes.reader ();
797 for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
798 (*x)->set_control_outs (cports);
802 /* load bundles, which we may have postponed earlier on */
803 if (_bundle_xml_node) {
804 load_bundles (*_bundle_xml_node);
805 delete _bundle_xml_node;
808 /* Tell all IO objects to connect themselves together */
810 IO::enable_connecting ();
812 /* Now reset all panners */
814 IO::reset_panners ();
816 /* Anyone who cares about input state, wake up and do something */
818 IOConnectionsComplete (); /* EMIT SIGNAL */
820 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting);
823 /* now handle the whole enchilada as if it was one
829 /* update mixer solo state */
835 Session::playlist_length_changed ()
837 /* we can't just increase end_location->end() if pl->get_maximum_extent()
838 if larger. if the playlist used to be the longest playlist,
839 and its now shorter, we have to decrease end_location->end(). hence,
840 we have to iterate over all diskstreams and check the
841 playlists currently in use.
847 Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
849 boost::shared_ptr<Playlist> playlist;
851 if ((playlist = dstream->playlist()) != 0) {
852 playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
855 /* see comment in playlist_length_changed () */
860 Session::record_enabling_legal () const
862 /* this used to be in here, but survey says.... we don't need to restrict it */
863 // if (record_status() == Recording) {
867 if (Config->get_all_safe()) {
874 Session::reset_input_monitor_state ()
876 if (transport_rolling()) {
878 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
880 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
881 if ((*i)->record_enabled ()) {
882 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
883 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input());
887 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
889 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
890 if ((*i)->record_enabled ()) {
891 //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl;
892 (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring);
899 Session::auto_punch_start_changed (Location* location)
901 replace_event (Event::PunchIn, location->start());
903 if (get_record_enabled() && Config->get_punch_in()) {
904 /* capture start has been changed, so save new pending state */
905 save_state ("", true);
910 Session::auto_punch_end_changed (Location* location)
912 nframes_t when_to_stop = location->end();
913 // when_to_stop += _worst_output_latency + _worst_input_latency;
914 replace_event (Event::PunchOut, when_to_stop);
918 Session::auto_punch_changed (Location* location)
920 nframes_t when_to_stop = location->end();
922 replace_event (Event::PunchIn, location->start());
923 //when_to_stop += _worst_output_latency + _worst_input_latency;
924 replace_event (Event::PunchOut, when_to_stop);
928 Session::auto_loop_changed (Location* location)
930 replace_event (Event::AutoLoop, location->end(), location->start());
932 if (transport_rolling() && play_loop) {
934 //if (_transport_frame < location->start() || _transport_frame > location->end()) {
936 if (_transport_frame > location->end()) {
937 // relocate to beginning of loop
938 clear_events (Event::LocateRoll);
940 request_locate (location->start(), true);
943 else if (Config->get_seamless_loop() && !loop_changing) {
945 // schedule a locate-roll to refill the diskstreams at the
947 loop_changing = true;
949 if (location->end() > last_loopend) {
950 clear_events (Event::LocateRoll);
951 Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true);
958 last_loopend = location->end();
962 Session::set_auto_punch_location (Location* location)
966 if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
967 auto_punch_start_changed_connection.disconnect();
968 auto_punch_end_changed_connection.disconnect();
969 auto_punch_changed_connection.disconnect();
970 existing->set_auto_punch (false, this);
971 remove_event (existing->start(), Event::PunchIn);
972 clear_events (Event::PunchOut);
973 auto_punch_location_changed (0);
982 if (location->end() <= location->start()) {
983 error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg;
987 auto_punch_start_changed_connection.disconnect();
988 auto_punch_end_changed_connection.disconnect();
989 auto_punch_changed_connection.disconnect();
991 auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed));
992 auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed));
993 auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed));
995 location->set_auto_punch (true, this);
998 auto_punch_changed (location);
1000 auto_punch_location_changed (location);
1004 Session::set_auto_loop_location (Location* location)
1008 if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
1009 auto_loop_start_changed_connection.disconnect();
1010 auto_loop_end_changed_connection.disconnect();
1011 auto_loop_changed_connection.disconnect();
1012 existing->set_auto_loop (false, this);
1013 remove_event (existing->end(), Event::AutoLoop);
1014 auto_loop_location_changed (0);
1019 if (location == 0) {
1023 if (location->end() <= location->start()) {
1024 error << _("Session: you can't use a mark for auto loop") << endmsg;
1028 last_loopend = location->end();
1030 auto_loop_start_changed_connection.disconnect();
1031 auto_loop_end_changed_connection.disconnect();
1032 auto_loop_changed_connection.disconnect();
1034 auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1035 auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed));
1036 auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed));
1038 location->set_auto_loop (true, this);
1040 /* take care of our stuff first */
1042 auto_loop_changed (location);
1044 /* now tell everyone else */
1046 auto_loop_location_changed (location);
1050 Session::locations_added (Location* ignored)
1056 Session::locations_changed ()
1058 _locations.apply (*this, &Session::handle_locations_changed);
1062 Session::handle_locations_changed (Locations::LocationList& locations)
1064 Locations::LocationList::iterator i;
1066 bool set_loop = false;
1067 bool set_punch = false;
1069 for (i = locations.begin(); i != locations.end(); ++i) {
1073 if (location->is_auto_punch()) {
1074 set_auto_punch_location (location);
1077 if (location->is_auto_loop()) {
1078 set_auto_loop_location (location);
1082 if (location->is_start()) {
1083 start_location = location;
1085 if (location->is_end()) {
1086 end_location = location;
1091 set_auto_loop_location (0);
1094 set_auto_punch_location (0);
1101 Session::enable_record ()
1103 /* XXX really atomic compare+swap here */
1104 if (g_atomic_int_get (&_record_status) != Recording) {
1105 g_atomic_int_set (&_record_status, Recording);
1106 _last_record_location = _transport_frame;
1107 deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
1109 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1110 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1111 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1112 if ((*i)->record_enabled ()) {
1113 (*i)->monitor_input (true);
1118 RecordStateChanged ();
1123 Session::disable_record (bool rt_context, bool force)
1127 if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) {
1129 if ((!Config->get_latched_record_enable () && !play_loop) || force) {
1130 g_atomic_int_set (&_record_status, Disabled);
1132 if (rs == Recording) {
1133 g_atomic_int_set (&_record_status, Enabled);
1137 // FIXME: timestamp correct? [DR]
1138 // FIXME FIXME FIXME: rt_context? this must be called in the process thread.
1139 // does this /need/ to be sent in all cases?
1141 deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
1143 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1144 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1146 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1147 if ((*i)->record_enabled ()) {
1148 (*i)->monitor_input (false);
1153 RecordStateChanged (); /* emit signal */
1156 remove_pending_capture_state ();
1162 Session::step_back_from_record ()
1164 /* XXX really atomic compare+swap here */
1165 if (g_atomic_int_get (&_record_status) == Recording) {
1166 g_atomic_int_set (&_record_status, Enabled);
1168 if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
1169 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1171 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1172 if ((*i)->record_enabled ()) {
1173 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
1174 (*i)->monitor_input (false);
1182 Session::maybe_enable_record ()
1184 g_atomic_int_set (&_record_status, Enabled);
1186 /* this function is currently called from somewhere other than an RT thread.
1187 this save_state() call therefore doesn't impact anything.
1190 save_state ("", true);
1192 if (_transport_speed) {
1193 if (!Config->get_punch_in()) {
1197 deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
1198 RecordStateChanged (); /* EMIT SIGNAL */
1205 Session::audible_frame () const
1211 /* the first of these two possible settings for "offset"
1212 mean that the audible frame is stationary until
1213 audio emerges from the latency compensation
1216 the second means that the audible frame is stationary
1217 until audio would emerge from a physical port
1218 in the absence of any plugin latency compensation
1221 offset = _worst_output_latency;
1223 if (offset > current_block_size) {
1224 offset -= current_block_size;
1226 /* XXX is this correct? if we have no external
1227 physical connections and everything is internal
1228 then surely this is zero? still, how
1229 likely is that anyway?
1231 offset = current_block_size;
1234 if (synced_to_jack()) {
1235 tf = _engine.transport_frame();
1237 tf = _transport_frame;
1242 if (!non_realtime_work_pending()) {
1246 /* check to see if we have passed the first guaranteed
1247 audible frame past our last start position. if not,
1248 return that last start point because in terms
1249 of audible frames, we have not moved yet.
1252 if (_transport_speed > 0.0f) {
1254 if (!play_loop || !have_looped) {
1255 if (tf < _last_roll_location + offset) {
1256 return _last_roll_location;
1264 } else if (_transport_speed < 0.0f) {
1266 /* XXX wot? no backward looping? */
1268 if (tf > _last_roll_location - offset) {
1269 return _last_roll_location;
1281 Session::set_frame_rate (nframes_t frames_per_second)
1283 /** \fn void Session::set_frame_size(nframes_t)
1284 the AudioEngine object that calls this guarantees
1285 that it will not be called while we are also in
1286 ::process(). Its fine to do things that block
1290 _base_frame_rate = frames_per_second;
1294 Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval())));
1298 // XXX we need some equivalent to this, somehow
1299 // SndFileSource::setup_standard_crossfades (frames_per_second);
1303 /* XXX need to reset/reinstantiate all LADSPA plugins */
1307 Session::set_block_size (nframes_t nframes)
1309 /* the AudioEngine guarantees
1310 that it will not be called while we are also in
1311 ::process(). It is therefore fine to do things that block
1317 current_block_size = nframes;
1319 ensure_buffers(_scratch_buffers->available());
1321 delete [] _gain_automation_buffer;
1322 _gain_automation_buffer = new gain_t[nframes];
1324 allocate_pan_automation_buffers (nframes, _npan_buffers, true);
1326 boost::shared_ptr<RouteList> r = routes.reader ();
1328 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1329 (*i)->set_block_size (nframes);
1332 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1333 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1334 (*i)->set_block_size (nframes);
1337 set_worst_io_latencies ();
1342 Session::set_default_fade (float steepness, float fade_msecs)
1345 nframes_t fade_frames;
1347 /* Don't allow fade of less 1 frame */
1349 if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) {
1356 fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001);
1360 default_fade_msecs = fade_msecs;
1361 default_fade_steepness = steepness;
1364 // jlc, WTF is this!
1365 Glib::RWLock::ReaderLock lm (route_lock);
1366 AudioRegion::set_default_fade (steepness, fade_frames);
1371 /* XXX have to do this at some point */
1372 /* foreach region using default fade, reset, then
1373 refill_all_diskstream_buffers ();
1378 struct RouteSorter {
1379 bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
1380 if (r1->fed_by.find (r2) != r1->fed_by.end()) {
1382 } else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
1385 if (r1->fed_by.empty()) {
1386 if (r2->fed_by.empty()) {
1387 /* no ardour-based connections inbound to either route. just use signal order */
1388 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1390 /* r2 has connections, r1 does not; run r1 early */
1394 return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
1401 trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
1403 shared_ptr<Route> r2;
1405 if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
1406 info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
1410 /* make a copy of the existing list of routes that feed r1 */
1412 set<shared_ptr<Route> > existing = r1->fed_by;
1414 /* for each route that feeds r1, recurse, marking it as feeding
1418 for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
1421 /* r2 is a route that feeds r1 which somehow feeds base. mark
1422 base as being fed by r2
1425 rbase->fed_by.insert (r2);
1429 /* 2nd level feedback loop detection. if r1 feeds or is fed by r2,
1433 if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) {
1437 /* now recurse, so that we can mark base as being fed by
1438 all routes that feed r2
1441 trace_terminal (r2, rbase);
1448 Session::resort_routes ()
1450 /* don't do anything here with signals emitted
1451 by Routes while we are being destroyed.
1454 if (_state_of_the_state & Deletion) {
1461 RCUWriter<RouteList> writer (routes);
1462 shared_ptr<RouteList> r = writer.get_copy ();
1463 resort_routes_using (r);
1464 /* writer goes out of scope and forces update */
1469 Session::resort_routes_using (shared_ptr<RouteList> r)
1471 RouteList::iterator i, j;
1473 for (i = r->begin(); i != r->end(); ++i) {
1475 (*i)->fed_by.clear ();
1477 for (j = r->begin(); j != r->end(); ++j) {
1479 /* although routes can feed themselves, it will
1480 cause an endless recursive descent if we
1481 detect it. so don't bother checking for
1489 if ((*j)->feeds (*i)) {
1490 (*i)->fed_by.insert (*j);
1495 for (i = r->begin(); i != r->end(); ++i) {
1496 trace_terminal (*i, *i);
1503 cerr << "finished route resort\n";
1505 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1506 cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
1513 list<boost::shared_ptr<MidiTrack> >
1514 Session::new_midi_track (TrackMode mode, uint32_t how_many)
1516 char track_name[32];
1517 uint32_t track_id = 0;
1520 RouteList new_routes;
1521 list<boost::shared_ptr<MidiTrack> > ret;
1522 //uint32_t control_id;
1524 // FIXME: need physical I/O and autoconnect stuff for MIDI
1526 /* count existing midi tracks */
1529 shared_ptr<RouteList> r = routes.reader ();
1531 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1532 if (boost::dynamic_pointer_cast<MidiTrack>(*i) != 0) {
1533 if (!(*i)->is_hidden()) {
1535 //channels_used += (*i)->n_inputs().n_midi();
1541 vector<string> physinputs;
1542 vector<string> physoutputs;
1544 _engine.get_physical_outputs (DataType::MIDI, physoutputs);
1545 _engine.get_physical_inputs (DataType::MIDI, physinputs);
1547 // control_id = ntracks() + nbusses();
1551 /* check for duplicate route names, since we might have pre-existing
1552 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1553 save, close,restart,add new route - first named route is now
1561 snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id);
1563 if (route_by_name (track_name) == 0) {
1567 } while (track_id < (UINT_MAX-1));
1569 shared_ptr<MidiTrack> track;
1572 track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode)));
1574 if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) {
1575 error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg;
1581 for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) {
1585 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1586 port = physinputs[(channels_used+x)%nphysical_in];
1589 if (port.length() && track->connect_input (track->input (x), port, this)) {
1595 for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) {
1599 if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) {
1600 port = physoutputs[(channels_used+x)%nphysical_out];
1601 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1603 port = _master_out->input (x%_master_out->n_inputs().n_midi())->name();
1607 if (port.length() && track->connect_output (track->output (x), port, this)) {
1612 channels_used += track->n_inputs ().n_midi();
1616 track->midi_diskstream()->non_realtime_input_change();
1618 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1619 //track->set_remote_control_id (control_id);
1621 new_routes.push_back (track);
1622 ret.push_back (track);
1625 catch (failed_constructor &err) {
1626 error << _("Session: could not create new midi track.") << endmsg;
1629 /* we need to get rid of this, since the track failed to be created */
1630 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1633 RCUWriter<DiskstreamList> writer (diskstreams);
1634 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1635 ds->remove (track->midi_diskstream());
1642 catch (AudioEngine::PortRegistrationFailure& pfe) {
1644 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;
1647 /* we need to get rid of this, since the track failed to be created */
1648 /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */
1651 RCUWriter<DiskstreamList> writer (diskstreams);
1652 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1653 ds->remove (track->midi_diskstream());
1664 if (!new_routes.empty()) {
1665 add_routes (new_routes, false);
1666 save_state (_current_snapshot_name);
1672 list<boost::shared_ptr<AudioTrack> >
1673 Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many)
1675 char track_name[32];
1676 uint32_t track_id = 0;
1678 uint32_t channels_used = 0;
1680 RouteList new_routes;
1681 list<boost::shared_ptr<AudioTrack> > ret;
1682 uint32_t control_id;
1684 /* count existing audio tracks */
1687 shared_ptr<RouteList> r = routes.reader ();
1689 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1690 if (boost::dynamic_pointer_cast<AudioTrack>(*i) != 0) {
1691 if (!(*i)->is_hidden()) {
1693 channels_used += (*i)->n_inputs().n_audio();
1699 vector<string> physinputs;
1700 vector<string> physoutputs;
1702 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1703 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1705 control_id = ntracks() + nbusses() + 1;
1709 /* check for duplicate route names, since we might have pre-existing
1710 routes with this name (e.g. create Audio1, Audio2, delete Audio1,
1711 save, close,restart,add new route - first named route is now
1719 snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id);
1721 if (route_by_name (track_name) == 0) {
1725 } while (track_id < (UINT_MAX-1));
1727 shared_ptr<AudioTrack> track;
1730 track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode)));
1732 if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1733 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1734 input_channels, output_channels)
1739 if (!physinputs.empty()) {
1740 uint32_t nphysical_in = physinputs.size();
1742 for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) {
1746 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1747 port = physinputs[(channels_used+x)%nphysical_in];
1750 if (port.length() && track->connect_input (track->input (x), port, this)) {
1756 if (!physoutputs.empty()) {
1757 uint32_t nphysical_out = physoutputs.size();
1759 for (uint32_t x = 0; x < track->n_outputs().n_audio(); ++x) {
1763 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1764 port = physoutputs[(channels_used+x)%nphysical_out];
1765 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1767 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1771 if (port.length() && track->connect_output (track->output (x), port, this)) {
1777 channels_used += track->n_inputs ().n_audio();
1779 track->audio_diskstream()->non_realtime_input_change();
1781 track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
1782 track->set_remote_control_id (control_id);
1785 new_routes.push_back (track);
1786 ret.push_back (track);
1789 catch (failed_constructor &err) {
1790 error << _("Session: could not create new audio track.") << endmsg;
1793 /* we need to get rid of this, since the track failed to be created */
1794 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1797 RCUWriter<DiskstreamList> writer (diskstreams);
1798 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1799 ds->remove (track->audio_diskstream());
1806 catch (AudioEngine::PortRegistrationFailure& pfe) {
1808 error << pfe.what() << endmsg;
1811 /* we need to get rid of this, since the track failed to be created */
1812 /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */
1815 RCUWriter<DiskstreamList> writer (diskstreams);
1816 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
1817 ds->remove (track->audio_diskstream());
1828 if (!new_routes.empty()) {
1829 add_routes (new_routes, true);
1836 Session::set_remote_control_ids ()
1838 RemoteModel m = Config->get_remote_model();
1840 shared_ptr<RouteList> r = routes.reader ();
1842 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1843 if ( MixerOrdered == m) {
1844 long order = (*i)->order_key(N_("signal"));
1845 (*i)->set_remote_control_id( order+1 );
1846 } else if ( EditorOrdered == m) {
1847 long order = (*i)->order_key(N_("editor"));
1848 (*i)->set_remote_control_id( order+1 );
1849 } else if ( UserOrdered == m) {
1850 //do nothing ... only changes to remote id's are initiated by user
1857 Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
1860 uint32_t bus_id = 1;
1862 uint32_t channels_used = 0;
1865 uint32_t control_id;
1867 /* count existing audio busses */
1870 shared_ptr<RouteList> r = routes.reader ();
1872 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1873 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
1875 if (!(*i)->is_hidden() && (*i)->name() != _("master")) {
1878 channels_used += (*i)->n_inputs().n_audio();
1884 vector<string> physinputs;
1885 vector<string> physoutputs;
1887 _engine.get_physical_outputs (DataType::AUDIO, physoutputs);
1888 _engine.get_physical_inputs (DataType::AUDIO, physinputs);
1890 n_physical_audio_outputs = physoutputs.size();
1891 n_physical_audio_inputs = physinputs.size();
1893 control_id = ntracks() + nbusses() + 1;
1898 snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id);
1902 if (route_by_name (bus_name) == 0) {
1906 } while (bus_id < (UINT_MAX-1));
1909 shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
1911 if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) {
1912 error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
1913 input_channels, output_channels)
1921 for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) {
1925 if (Config->get_input_auto_connect() & AutoConnectPhysical) {
1926 port = physinputs[((n+x)%n_physical_audio_inputs)];
1929 if (port.length() && bus->connect_input (bus->input (x), port, this)) {
1935 for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) {
1938 if (Config->get_output_auto_connect() & AutoConnectPhysical) {
1939 port = physoutputs[((n+x)%n_physical_outputs)];
1940 } else if (Config->get_output_auto_connect() & AutoConnectMaster) {
1942 port = _master_out->input (x%_master_out->n_inputs().n_audio())->name();
1946 if (port.length() && bus->connect_output (bus->output (x), port, this)) {
1951 channels_used += bus->n_inputs ().n_audio();
1953 bus->set_remote_control_id (control_id);
1956 ret.push_back (bus);
1960 catch (failed_constructor &err) {
1961 error << _("Session: could not create new audio route.") << endmsg;
1965 catch (AudioEngine::PortRegistrationFailure& pfe) {
1966 error << pfe.what() << endmsg;
1976 add_routes (ret, true);
1984 Session::new_route_from_template (uint32_t how_many, const std::string& template_path)
1988 uint32_t control_id;
1991 if (!tree.read (template_path.c_str())) {
1995 XMLNode* node = tree.root();
1997 control_id = ntracks() + nbusses() + 1;
2001 XMLNode node_copy (*node); // make a copy so we can change the name if we need to
2003 std::string node_name = IO::name_from_state (*node_copy.children().front());
2005 if (route_by_name (node_name) != 0) {
2007 /* generate a new name by adding a number to the end of the template name */
2009 uint32_t number = 1;
2012 snprintf (name, sizeof (name), "%s %" PRIu32, node_name.c_str(), number);
2016 if (route_by_name (name) == 0) {
2020 } while (number < UINT_MAX);
2022 if (number == UINT_MAX) {
2023 fatal << _("Session: UINT_MAX routes? impossible!") << endmsg;
2027 IO::set_name_in_state (*node_copy.children().front(), name);
2030 Track::zero_diskstream_id_in_xml (node_copy);
2033 shared_ptr<Route> route (XMLRouteFactory (node_copy));
2036 error << _("Session: cannot create track/bus from template description") << endmsg;
2040 if (boost::dynamic_pointer_cast<Track>(route)) {
2041 /* force input/output change signals so that the new diskstream
2042 picks up the configuration of the route. During session
2043 loading this normally happens in a different way.
2045 route->input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2046 route->output_changed (IOChange (ConfigurationChanged|ConnectionsChanged), this);
2049 route->set_remote_control_id (control_id);
2052 ret.push_back (route);
2055 catch (failed_constructor &err) {
2056 error << _("Session: could not create new route from template") << endmsg;
2060 catch (AudioEngine::PortRegistrationFailure& pfe) {
2061 error << pfe.what() << endmsg;
2070 add_routes (ret, true);
2077 Session::add_routes (RouteList& new_routes, bool save)
2080 RCUWriter<RouteList> writer (routes);
2081 shared_ptr<RouteList> r = writer.get_copy ();
2082 r->insert (r->end(), new_routes.begin(), new_routes.end());
2083 resort_routes_using (r);
2086 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2088 boost::weak_ptr<Route> wpr (*x);
2090 (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
2091 (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
2092 (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
2093 (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
2095 if ((*x)->is_master()) {
2099 if ((*x)->is_control()) {
2100 _control_out = (*x);
2104 if (_control_out && IO::connecting_legal) {
2106 vector<string> cports;
2107 uint32_t ni = _control_out->n_inputs().n_audio();
2109 for (uint32_t n = 0; n < ni; ++n) {
2110 cports.push_back (_control_out->input(n)->name());
2113 for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
2114 (*x)->set_control_outs (cports);
2121 save_state (_current_snapshot_name);
2124 RouteAdded (new_routes); /* EMIT SIGNAL */
2128 Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
2130 /* need to do this in case we're rolling at the time, to prevent false underruns */
2131 dstream->do_refill_with_alloc ();
2133 dstream->set_block_size (current_block_size);
2136 RCUWriter<DiskstreamList> writer (diskstreams);
2137 boost::shared_ptr<DiskstreamList> ds = writer.get_copy();
2138 ds->push_back (dstream);
2139 /* writer goes out of scope, copies ds back to main */
2142 dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream));
2143 /* this will connect to future changes, and check the current length */
2144 diskstream_playlist_changed (dstream);
2146 dstream->RecordEnableChanged.connect (mem_fun (*this, &Session::update_have_rec_enabled_diskstream));
2148 dstream->prepare ();
2153 Session::remove_route (shared_ptr<Route> route)
2156 RCUWriter<RouteList> writer (routes);
2157 shared_ptr<RouteList> rs = writer.get_copy ();
2161 /* deleting the master out seems like a dumb
2162 idea, but its more of a UI policy issue
2166 if (route == _master_out) {
2167 _master_out = shared_ptr<Route> ();
2170 if (route == _control_out) {
2171 _control_out = shared_ptr<Route> ();
2173 /* cancel control outs for all routes */
2175 vector<string> empty;
2177 for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
2178 (*r)->set_control_outs (empty);
2182 update_route_solo_state ();
2184 /* writer goes out of scope, forces route list update */
2187 boost::shared_ptr<Track> t;
2188 boost::shared_ptr<Diskstream> ds;
2190 if ((t = boost::dynamic_pointer_cast<Track>(route)) != 0) {
2191 ds = t->diskstream();
2197 RCUWriter<DiskstreamList> dsl (diskstreams);
2198 boost::shared_ptr<DiskstreamList> d = dsl.get_copy();
2203 find_current_end ();
2205 // We need to disconnect the routes inputs and outputs
2207 route->disconnect_inputs (0);
2208 route->disconnect_outputs (0);
2210 update_latency_compensation (false, false);
2213 /* get rid of it from the dead wood collection in the route list manager */
2215 /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */
2219 /* try to cause everyone to drop their references */
2221 route->drop_references ();
2223 sync_order_keys (N_("session"));
2225 /* save the new state of the world */
2227 if (save_state (_current_snapshot_name)) {
2228 save_history (_current_snapshot_name);
2233 Session::route_mute_changed (void* src)
2239 Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr)
2241 if (solo_update_disabled) {
2247 boost::shared_ptr<Route> route = wpr.lock ();
2250 /* should not happen */
2251 error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg;
2255 is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0);
2257 shared_ptr<RouteList> r = routes.reader ();
2259 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2261 /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
2265 /* don't mess with busses */
2267 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
2273 /* don't mess with tracks */
2275 if (boost::dynamic_pointer_cast<Track>(*i) != 0) {
2280 if ((*i) != route &&
2281 ((*i)->mix_group () == 0 ||
2282 (*i)->mix_group () != route->mix_group () ||
2283 !route->mix_group ()->is_active())) {
2285 if ((*i)->soloed()) {
2287 /* if its already soloed, and solo latching is enabled,
2288 then leave it as it is.
2291 if (Config->get_solo_latched()) {
2298 solo_update_disabled = true;
2299 (*i)->set_solo (false, src);
2300 solo_update_disabled = false;
2304 bool something_soloed = false;
2305 bool same_thing_soloed = false;
2306 bool signal = false;
2308 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2309 if ((*i)->soloed()) {
2310 something_soloed = true;
2311 if (boost::dynamic_pointer_cast<Track>(*i)) {
2313 same_thing_soloed = true;
2318 same_thing_soloed = true;
2326 if (something_soloed != currently_soloing) {
2328 currently_soloing = something_soloed;
2331 modify_solo_mute (is_track, same_thing_soloed);
2334 SoloActive (currently_soloing); /* EMIT SIGNAL */
2337 SoloChanged (); /* EMIT SIGNAL */
2343 Session::update_route_solo_state ()
2346 bool is_track = false;
2347 bool signal = false;
2349 /* this is where we actually implement solo by changing
2350 the solo mute setting of each track.
2353 shared_ptr<RouteList> r = routes.reader ();
2355 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2356 if ((*i)->soloed()) {
2358 if (boost::dynamic_pointer_cast<Track>(*i)) {
2365 if (mute != currently_soloing) {
2367 currently_soloing = mute;
2370 if (!is_track && !mute) {
2372 /* nothing is soloed */
2374 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2375 (*i)->set_solo_mute (false);
2385 modify_solo_mute (is_track, mute);
2388 SoloActive (currently_soloing);
2393 Session::modify_solo_mute (bool is_track, bool mute)
2395 shared_ptr<RouteList> r = routes.reader ();
2397 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2401 /* only alter track solo mute */
2403 if (boost::dynamic_pointer_cast<Track>(*i)) {
2404 if ((*i)->soloed()) {
2405 (*i)->set_solo_mute (!mute);
2407 (*i)->set_solo_mute (mute);
2413 /* only alter bus solo mute */
2415 if (!boost::dynamic_pointer_cast<Track>(*i)) {
2417 if ((*i)->soloed()) {
2419 (*i)->set_solo_mute (false);
2423 /* don't mute master or control outs
2424 in response to another bus solo
2427 if ((*i) != _master_out &&
2428 (*i) != _control_out) {
2429 (*i)->set_solo_mute (mute);
2440 Session::catch_up_on_solo ()
2442 /* this is called after set_state() to catch the full solo
2443 state, which can't be correctly determined on a per-route
2444 basis, but needs the global overview that only the session
2447 update_route_solo_state();
2451 Session::catch_up_on_solo_mute_override ()
2453 if (Config->get_solo_model() != InverseMute) {
2457 /* this is called whenever the param solo-mute-override is
2460 shared_ptr<RouteList> r = routes.reader ();
2462 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2463 (*i)->catch_up_on_solo_mute_override ();
2468 Session::route_by_name (string name)
2470 shared_ptr<RouteList> r = routes.reader ();
2472 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2473 if ((*i)->name() == name) {
2478 return shared_ptr<Route> ((Route*) 0);
2482 Session::route_by_id (PBD::ID id)
2484 shared_ptr<RouteList> r = routes.reader ();
2486 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2487 if ((*i)->id() == id) {
2492 return shared_ptr<Route> ((Route*) 0);
2496 Session::route_by_remote_id (uint32_t id)
2498 shared_ptr<RouteList> r = routes.reader ();
2500 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2501 if ((*i)->remote_control_id() == id) {
2506 return shared_ptr<Route> ((Route*) 0);
2510 Session::find_current_end ()
2512 if (_state_of_the_state & Loading) {
2516 nframes_t max = get_maximum_extent ();
2518 if (max > end_location->end()) {
2519 end_location->set_end (max);
2521 DurationChanged(); /* EMIT SIGNAL */
2526 Session::get_maximum_extent () const
2531 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2533 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
2534 if ((*i)->destructive()) //ignore tape tracks when getting max extents
2536 boost::shared_ptr<Playlist> pl = (*i)->playlist();
2537 if ((me = pl->get_maximum_extent()) > max) {
2545 boost::shared_ptr<Diskstream>
2546 Session::diskstream_by_name (string name)
2548 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2550 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2551 if ((*i)->name() == name) {
2556 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2559 boost::shared_ptr<Diskstream>
2560 Session::diskstream_by_id (const PBD::ID& id)
2562 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2564 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2565 if ((*i)->id() == id) {
2570 return boost::shared_ptr<Diskstream>((Diskstream*) 0);
2573 /* Region management */
2576 Session::new_region_name (string old)
2578 string::size_type last_period;
2580 string::size_type len = old.length() + 64;
2583 if ((last_period = old.find_last_of ('.')) == string::npos) {
2585 /* no period present - add one explicitly */
2588 last_period = old.length() - 1;
2593 number = atoi (old.substr (last_period+1).c_str());
2597 while (number < (UINT_MAX-1)) {
2599 RegionList::const_iterator i;
2604 snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
2607 for (i = regions.begin(); i != regions.end(); ++i) {
2608 if (i->second->name() == sbuf) {
2613 if (i == regions.end()) {
2618 if (number != (UINT_MAX-1)) {
2622 error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg;
2627 Session::region_name (string& result, string base, bool newlevel)
2632 if (base.find("/") != string::npos) {
2633 base = base.substr(base.find_last_of("/") + 1);
2638 Glib::Mutex::Lock lm (region_lock);
2640 snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
2649 string::size_type pos;
2651 pos = base.find_last_of ('.');
2653 /* pos may be npos, but then we just use entire base */
2655 subbase = base.substr (0, pos);
2660 Glib::Mutex::Lock lm (region_lock);
2662 map<string,uint32_t>::iterator x;
2666 if ((x = region_name_map.find (subbase)) == region_name_map.end()) {
2668 region_name_map[subbase] = 1;
2671 snprintf (buf, sizeof (buf), ".%d", x->second);
2682 Session::add_region (boost::shared_ptr<Region> region)
2684 vector<boost::shared_ptr<Region> > v;
2685 v.push_back (region);
2690 Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions)
2695 Glib::Mutex::Lock lm (region_lock);
2697 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2699 boost::shared_ptr<Region> region = *ii;
2703 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2707 RegionList::iterator x;
2709 for (x = regions.begin(); x != regions.end(); ++x) {
2711 if (region->region_list_equivalent (x->second)) {
2716 if (x == regions.end()) {
2718 pair<RegionList::key_type,RegionList::mapped_type> entry;
2720 entry.first = region->id();
2721 entry.second = region;
2723 pair<RegionList::iterator,bool> x = regions.insert (entry);
2735 /* mark dirty because something has changed even if we didn't
2736 add the region to the region list.
2743 vector<boost::weak_ptr<Region> > v;
2744 boost::shared_ptr<Region> first_r;
2746 for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) {
2748 boost::shared_ptr<Region> region = *ii;
2752 error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg;
2755 v.push_back (region);
2762 region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region)));
2763 region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region)));
2765 update_region_name_map (region);
2769 RegionsAdded (v); /* EMIT SIGNAL */
2775 Session::update_region_name_map (boost::shared_ptr<Region> region)
2777 string::size_type last_period = region->name().find_last_of ('.');
2779 if (last_period != string::npos && last_period < region->name().length() - 1) {
2781 string base = region->name().substr (0, last_period);
2782 string number = region->name().substr (last_period+1);
2783 map<string,uint32_t>::iterator x;
2785 /* note that if there is no number, we get zero from atoi,
2789 region_name_map[base] = atoi (number);
2794 Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region)
2796 boost::shared_ptr<Region> region (weak_region.lock ());
2802 if (what_changed & Region::HiddenChanged) {
2803 /* relay hidden changes */
2804 RegionHiddenChange (region);
2807 if (what_changed & NameChanged) {
2808 update_region_name_map (region);
2813 Session::remove_region (boost::weak_ptr<Region> weak_region)
2815 RegionList::iterator i;
2816 boost::shared_ptr<Region> region (weak_region.lock ());
2822 bool removed = false;
2825 Glib::Mutex::Lock lm (region_lock);
2827 if ((i = regions.find (region->id())) != regions.end()) {
2833 /* mark dirty because something has changed even if we didn't
2834 remove the region from the region list.
2840 RegionRemoved(region); /* EMIT SIGNAL */
2844 boost::shared_ptr<Region>
2845 Session::find_whole_file_parent (boost::shared_ptr<Region const> child)
2847 RegionList::iterator i;
2848 boost::shared_ptr<Region> region;
2850 Glib::Mutex::Lock lm (region_lock);
2852 for (i = regions.begin(); i != regions.end(); ++i) {
2856 if (region->whole_file()) {
2858 if (child->source_equivalent (region)) {
2864 return boost::shared_ptr<Region> ();
2868 Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
2870 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
2871 (*i)->get_region_list_equivalent_regions (region, result);
2875 Session::destroy_region (boost::shared_ptr<Region> region)
2877 vector<boost::shared_ptr<Source> > srcs;
2880 if (region->playlist()) {
2881 region->playlist()->destroy_region (region);
2884 for (uint32_t n = 0; n < region->n_channels(); ++n) {
2885 srcs.push_back (region->source (n));
2889 region->drop_references ();
2891 for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
2893 (*i)->mark_for_remove ();
2894 (*i)->drop_references ();
2896 cerr << "source was not used by any playlist\n";
2903 Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
2905 for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
2906 destroy_region (*i);
2912 Session::remove_last_capture ()
2914 list<boost::shared_ptr<Region> > r;
2916 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2918 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2919 list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
2922 r.insert (r.end(), l.begin(), l.end());
2927 destroy_regions (r);
2929 save_state (_current_snapshot_name);
2935 Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
2941 /* Source Management */
2944 Session::add_source (boost::shared_ptr<Source> source)
2946 pair<SourceMap::key_type, SourceMap::mapped_type> entry;
2947 pair<SourceMap::iterator,bool> result;
2949 entry.first = source->id();
2950 entry.second = source;
2953 Glib::Mutex::Lock lm (source_lock);
2954 result = sources.insert (entry);
2957 if (result.second) {
2958 source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
2962 boost::shared_ptr<AudioFileSource> afs;
2964 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
2965 if (Config->get_auto_analyse_audio()) {
2966 Analyser::queue_source_for_analysis (source, false);
2972 Session::remove_source (boost::weak_ptr<Source> src)
2974 SourceMap::iterator i;
2975 boost::shared_ptr<Source> source = src.lock();
2982 Glib::Mutex::Lock lm (source_lock);
2984 if ((i = sources.find (source->id())) != sources.end()) {
2989 if (!_state_of_the_state & InCleanup) {
2991 /* save state so we don't end up with a session file
2992 referring to non-existent sources.
2995 save_state (_current_snapshot_name);
2999 boost::shared_ptr<Source>
3000 Session::source_by_id (const PBD::ID& id)
3002 Glib::Mutex::Lock lm (source_lock);
3003 SourceMap::iterator i;
3004 boost::shared_ptr<Source> source;
3006 if ((i = sources.find (id)) != sources.end()) {
3013 boost::shared_ptr<Source>
3014 Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
3016 Glib::Mutex::Lock lm (source_lock);
3018 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3019 cerr << "comparing " << path << " with " << i->second->name() << endl;
3020 boost::shared_ptr<AudioFileSource> afs
3021 = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
3023 if (afs && afs->path() == path && chn == afs->channel()) {
3027 return boost::shared_ptr<Source>();
3032 Session::change_source_path_by_name (string path, string oldname, string newname, bool destructive)
3035 string old_basename = PBD::basename_nosuffix (oldname);
3036 string new_legalized = legalize_for_path (newname);
3038 /* note: we know (or assume) the old path is already valid */
3042 /* destructive file sources have a name of the form:
3044 /path/to/Tnnnn-NAME(%[LR])?.wav
3046 the task here is to replace NAME with the new name.
3049 /* find last slash */
3053 string::size_type slash;
3054 string::size_type dash;
3056 if ((slash = path.find_last_of ('/')) == string::npos) {
3060 dir = path.substr (0, slash+1);
3062 /* '-' is not a legal character for the NAME part of the path */
3064 if ((dash = path.find_last_of ('-')) == string::npos) {
3068 prefix = path.substr (slash+1, dash-(slash+1));
3073 path += new_legalized;
3074 path += ".wav"; /* XXX gag me with a spoon */
3078 /* non-destructive file sources have a name of the form:
3080 /path/to/NAME-nnnnn(%[LR])?.ext
3082 the task here is to replace NAME with the new name.
3087 string::size_type slash;
3088 string::size_type dash;
3089 string::size_type postfix;
3091 /* find last slash */
3093 if ((slash = path.find_last_of ('/')) == string::npos) {
3097 dir = path.substr (0, slash+1);
3099 /* '-' is not a legal character for the NAME part of the path */
3101 if ((dash = path.find_last_of ('-')) == string::npos) {
3105 suffix = path.substr (dash+1);
3107 // Suffix is now everything after the dash. Now we need to eliminate
3108 // the nnnnn part, which is done by either finding a '%' or a '.'
3110 postfix = suffix.find_last_of ("%");
3111 if (postfix == string::npos) {
3112 postfix = suffix.find_last_of ('.');
3115 if (postfix != string::npos) {
3116 suffix = suffix.substr (postfix);
3118 error << "Logic error in Session::change_source_path_by_name(), please report" << endl;
3122 const uint32_t limit = 10000;
3123 char buf[PATH_MAX+1];
3125 for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
3127 snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
3129 if (access (buf, F_OK) != 0) {
3137 error << "FATAL ERROR! Could not find a " << endl;
3145 /** Return the full path (in some session directory) for a new embedded source.
3146 * \a name must be a session-unique name that does not contain slashes
3147 * (e.g. as returned by new_*_source_name)
3150 Session::new_source_path_from_name (DataType type, const string& name)
3152 assert(name.find("/") == string::npos);
3154 SessionDirectory sdir(get_best_session_directory_for_new_source());
3157 if (type == DataType::AUDIO) {
3158 p = sdir.sound_path();
3159 } else if (type == DataType::MIDI) {
3160 p = sdir.midi_path();
3162 error << "Unknown source type, unable to create file path" << endmsg;
3167 return p.to_string();
3171 Session::peak_path (Glib::ustring base) const
3173 sys::path peakfile_path(_session_dir->peak_path());
3174 peakfile_path /= basename_nosuffix (base) + peakfile_suffix;
3175 return peakfile_path.to_string();
3178 /** Return a unique name based on \a base for a new internal audio source */
3180 Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t chan, bool destructive)
3184 char buf[PATH_MAX+1];
3185 const uint32_t limit = 10000;
3189 legalized = legalize_for_path (base);
3191 // Find a "version" of the base name that doesn't exist in any of the possible directories.
3192 for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
3194 vector<space_and_path>::iterator i;
3195 uint32_t existing = 0;
3197 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3199 SessionDirectory sdir((*i).path);
3201 spath = sdir.sound_path().to_string();
3206 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3207 spath.c_str(), cnt, legalized.c_str());
3208 } else if (nchan == 2) {
3210 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav",
3211 spath.c_str(), cnt, legalized.c_str());
3213 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav",
3214 spath.c_str(), cnt, legalized.c_str());
3216 } else if (nchan < 26) {
3217 snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav",
3218 spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
3220 snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav",
3221 spath.c_str(), cnt, legalized.c_str());
3230 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3231 } else if (nchan == 2) {
3233 snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
3235 snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
3237 } else if (nchan < 26) {
3238 snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
3240 snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
3244 if (sys::exists(buf)) {
3250 if (existing == 0) {
3255 error << string_compose(
3256 _("There are already %1 recordings for %2, which I consider too many."),
3257 limit, base) << endmsg;
3259 throw failed_constructor();
3263 return Glib::path_get_basename(buf);
3266 /** Create a new embedded audio source */
3267 boost::shared_ptr<AudioFileSource>
3268 Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
3270 const size_t n_chans = ds.n_channels().n_audio();
3271 const string name = new_audio_source_name (ds.name(), n_chans, chan, destructive);
3272 const string path = new_source_path_from_name(DataType::AUDIO, name);
3273 return boost::dynamic_pointer_cast<AudioFileSource> (
3274 SourceFactory::createWritable (
3275 DataType::AUDIO, *this, path, true, destructive, frame_rate()));
3278 /** Return a unique name based on \a base for a new internal MIDI source */
3280 Session::new_midi_source_name (const string& base)
3283 char buf[PATH_MAX+1];
3284 const uint32_t limit = 10000;
3288 legalized = legalize_for_path (base);
3290 // Find a "version" of the file name that doesn't exist in any of the possible directories.
3291 for (cnt = 1; cnt <= limit; ++cnt) {
3293 vector<space_and_path>::iterator i;
3294 uint32_t existing = 0;
3296 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3298 SessionDirectory sdir((*i).path);
3300 sys::path p = sdir.midi_path();
3303 snprintf (buf, sizeof(buf), "%s-%u.mid", p.to_string().c_str(), cnt);
3305 if (sys::exists (buf)) {
3310 if (existing == 0) {
3315 error << string_compose(
3316 _("There are already %1 recordings for %2, which I consider too many."),
3317 limit, base) << endmsg;
3319 throw failed_constructor();
3323 return Glib::path_get_basename(buf);
3327 /** Create a new embedded MIDI source */
3328 boost::shared_ptr<MidiSource>
3329 Session::create_midi_source_for_session (MidiDiskstream& ds)
3331 const string name = new_midi_source_name (ds.name());
3332 const string path = new_source_path_from_name (DataType::MIDI, name);
3334 return boost::dynamic_pointer_cast<SMFSource> (
3335 SourceFactory::createWritable (
3336 DataType::MIDI, *this, path, true, false, frame_rate()));
3340 /* Playlist management */
3342 boost::shared_ptr<Playlist>
3343 Session::playlist_by_name (string name)
3345 Glib::Mutex::Lock lm (playlist_lock);
3346 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3347 if ((*i)->name() == name) {
3351 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3352 if ((*i)->name() == name) {
3357 return boost::shared_ptr<Playlist>();
3361 Session::unassigned_playlists (std::list<boost::shared_ptr<Playlist> > & list)
3363 Glib::Mutex::Lock lm (playlist_lock);
3364 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3365 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3366 list.push_back (*i);
3369 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3370 if (!(*i)->get_orig_diskstream_id().to_s().compare ("0")) {
3371 list.push_back (*i);
3377 Session::add_playlist (boost::shared_ptr<Playlist> playlist, bool unused)
3379 if (playlist->hidden()) {
3384 Glib::Mutex::Lock lm (playlist_lock);
3385 if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
3386 playlists.insert (playlists.begin(), playlist);
3387 playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
3388 playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
3393 playlist->release();
3398 PlaylistAdded (playlist); /* EMIT SIGNAL */
3402 Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
3405 Glib::Mutex::Lock lm (playlist_lock);
3406 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3409 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3416 Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
3418 boost::shared_ptr<Playlist> pl(wpl.lock());
3424 PlaylistList::iterator x;
3427 /* its not supposed to be visible */
3432 Glib::Mutex::Lock lm (playlist_lock);
3436 unused_playlists.insert (pl);
3438 if ((x = playlists.find (pl)) != playlists.end()) {
3439 playlists.erase (x);
3445 playlists.insert (pl);
3447 if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
3448 unused_playlists.erase (x);
3455 Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
3457 if (_state_of_the_state & Deletion) {
3461 boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
3468 Glib::Mutex::Lock lm (playlist_lock);
3470 PlaylistList::iterator i;
3472 i = find (playlists.begin(), playlists.end(), playlist);
3473 if (i != playlists.end()) {
3474 playlists.erase (i);
3477 i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
3478 if (i != unused_playlists.end()) {
3479 unused_playlists.erase (i);
3486 PlaylistRemoved (playlist); /* EMIT SIGNAL */
3490 Session::set_audition (boost::shared_ptr<Region> r)
3492 pending_audition_region = r;
3493 post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
3494 schedule_butler_transport_work ();
3498 Session::audition_playlist ()
3500 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3501 ev->region.reset ();
3506 Session::non_realtime_set_audition ()
3508 if (!pending_audition_region) {
3509 auditioner->audition_current_playlist ();
3511 auditioner->audition_region (pending_audition_region);
3512 pending_audition_region.reset ();
3514 AuditionActive (true); /* EMIT SIGNAL */
3518 Session::audition_region (boost::shared_ptr<Region> r)
3520 Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
3526 Session::cancel_audition ()
3528 if (auditioner->active()) {
3529 auditioner->cancel_audition ();
3530 AuditionActive (false); /* EMIT SIGNAL */
3535 Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
3537 return a->order_key(N_("signal")) < b->order_key(N_("signal"));
3541 Session::remove_empty_sounds ()
3543 vector<string> audio_filenames;
3545 get_files_in_directory (_session_dir->sound_path(), audio_filenames);
3547 Glib::Mutex::Lock lm (source_lock);
3549 TapeFileMatcher tape_file_matcher;
3551 remove_if (audio_filenames.begin(), audio_filenames.end(),
3552 sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches));
3554 for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
3556 sys::path audio_file_path (_session_dir->sound_path());
3558 audio_file_path /= *i;
3560 if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
3564 sys::remove (audio_file_path);
3565 const string peakfile = peak_path (audio_file_path.to_string());
3566 sys::remove (peakfile);
3568 catch (const sys::filesystem_error& err)
3570 error << err.what() << endmsg;
3577 Session::is_auditioning () const
3579 /* can be called before we have an auditioner object */
3581 return auditioner->active();
3588 Session::set_all_solo (bool yn)
3590 shared_ptr<RouteList> r = routes.reader ();
3592 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3593 if (!(*i)->is_hidden()) {
3594 (*i)->set_solo (yn, this);
3602 Session::set_all_mute (bool yn)
3604 shared_ptr<RouteList> r = routes.reader ();
3606 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3607 if (!(*i)->is_hidden()) {
3608 (*i)->set_mute (yn, this);
3616 Session::n_diskstreams () const
3620 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3622 for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
3623 if (!(*i)->hidden()) {
3631 Session::graph_reordered ()
3633 /* don't do this stuff if we are setting up connections
3634 from a set_state() call or creating new tracks.
3637 if (_state_of_the_state & InitialConnecting) {
3641 /* every track/bus asked for this to be handled but it was deferred because
3642 we were connecting. do it now.
3645 request_input_change_handling ();
3649 /* force all diskstreams to update their capture offset values to
3650 reflect any changes in latencies within the graph.
3653 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3655 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3656 (*i)->set_capture_offset ();
3661 Session::record_disenable_all ()
3663 record_enable_change_all (false);
3667 Session::record_enable_all ()
3669 record_enable_change_all (true);
3673 Session::record_enable_change_all (bool yn)
3675 shared_ptr<RouteList> r = routes.reader ();
3677 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
3678 boost::shared_ptr<Track> t;
3680 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
3681 t->set_record_enable (yn, this);
3685 /* since we don't keep rec-enable state, don't mark session dirty */
3689 Session::add_processor (Processor* processor)
3692 PortInsert* port_insert;
3693 PluginInsert* plugin_insert;
3695 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3696 _port_inserts.insert (_port_inserts.begin(), port_insert);
3697 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3698 _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
3699 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3700 _sends.insert (_sends.begin(), send);
3702 fatal << _("programming error: unknown type of Insert created!") << endmsg;
3706 processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor));
3712 Session::remove_processor (Processor* processor)
3715 PortInsert* port_insert;
3716 PluginInsert* plugin_insert;
3718 if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
3719 list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
3720 if (x != _port_inserts.end()) {
3721 insert_bitset[port_insert->bit_slot()] = false;
3722 _port_inserts.erase (x);
3724 } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
3725 _plugin_inserts.remove (plugin_insert);
3726 } else if ((send = dynamic_cast<Send *> (processor)) != 0) {
3727 list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
3728 if (x != _sends.end()) {
3729 send_bitset[send->bit_slot()] = false;
3733 fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
3741 Session::available_capture_duration ()
3743 float sample_bytes_on_disk = 4.0; // keep gcc happy
3745 switch (Config->get_native_file_data_format()) {
3747 sample_bytes_on_disk = 4.0;
3751 sample_bytes_on_disk = 3.0;
3755 sample_bytes_on_disk = 2.0;
3759 /* impossible, but keep some gcc versions happy */
3760 fatal << string_compose (_("programming error: %1"),
3761 X_("illegal native file data format"))
3766 double scale = 4096.0 / sample_bytes_on_disk;
3768 if (_total_free_4k_blocks * scale > (double) max_frames) {
3772 return (nframes_t) floor (_total_free_4k_blocks * scale);
3776 Session::add_bundle (shared_ptr<Bundle> bundle)
3779 RCUWriter<BundleList> writer (_bundles);
3780 boost::shared_ptr<BundleList> b = writer.get_copy ();
3781 b->push_back (bundle);
3784 BundleAdded (bundle); /* EMIT SIGNAL */
3790 Session::remove_bundle (shared_ptr<Bundle> bundle)
3792 bool removed = false;
3795 RCUWriter<BundleList> writer (_bundles);
3796 boost::shared_ptr<BundleList> b = writer.get_copy ();
3797 BundleList::iterator i = find (b->begin(), b->end(), bundle);
3799 if (i != b->end()) {
3806 BundleRemoved (bundle); /* EMIT SIGNAL */
3813 Session::bundle_by_name (string name) const
3815 boost::shared_ptr<BundleList> b = _bundles.reader ();
3817 for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
3818 if ((*i)->name() == name) {
3823 return boost::shared_ptr<Bundle> ();
3827 Session::tempo_map_changed (Change ignored)
3831 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3832 (*i)->update_after_tempo_map_change ();
3835 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
3836 (*i)->update_after_tempo_map_change ();
3842 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
3843 * the given count with the current block size.
3846 Session::ensure_buffers (ChanCount howmany)
3848 if (current_block_size == 0) {
3849 return; // too early? (is this ok?)
3852 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3853 size_t count = std::max(_scratch_buffers->available().get(*t), howmany.get(*t));
3854 _scratch_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3855 _mix_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3856 _silent_buffers->ensure_buffers (*t, count, _engine.raw_buffer_size(*t));
3859 allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false);
3863 Session::ensure_buffer_set(BufferSet& buffers, const ChanCount& count)
3865 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3866 buffers.ensure_buffers(*t, count.get(*t), _engine.raw_buffer_size(*t));
3871 Session::next_insert_id ()
3873 /* this doesn't really loop forever. just think about it */
3876 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) {
3877 if (!insert_bitset[n]) {
3878 insert_bitset[n] = true;
3884 /* none available, so resize and try again */
3886 insert_bitset.resize (insert_bitset.size() + 16, false);
3891 Session::next_send_id ()
3893 /* this doesn't really loop forever. just think about it */
3896 for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) {
3897 if (!send_bitset[n]) {
3898 send_bitset[n] = true;
3904 /* none available, so resize and try again */
3906 send_bitset.resize (send_bitset.size() + 16, false);
3911 Session::mark_send_id (uint32_t id)
3913 if (id >= send_bitset.size()) {
3914 send_bitset.resize (id+16, false);
3916 if (send_bitset[id]) {
3917 warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg;
3919 send_bitset[id] = true;
3923 Session::mark_insert_id (uint32_t id)
3925 if (id >= insert_bitset.size()) {
3926 insert_bitset.resize (id+16, false);
3928 if (insert_bitset[id]) {
3929 warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg;
3931 insert_bitset[id] = true;
3934 /* Named Selection management */
3937 Session::named_selection_by_name (string name)
3939 Glib::Mutex::Lock lm (named_selection_lock);
3940 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
3941 if ((*i)->name == name) {
3949 Session::add_named_selection (NamedSelection* named_selection)
3952 Glib::Mutex::Lock lm (named_selection_lock);
3953 named_selections.insert (named_selections.begin(), named_selection);
3956 for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
3962 NamedSelectionAdded (); /* EMIT SIGNAL */
3966 Session::remove_named_selection (NamedSelection* named_selection)
3968 bool removed = false;
3971 Glib::Mutex::Lock lm (named_selection_lock);
3973 NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection);
3975 if (i != named_selections.end()) {
3977 named_selections.erase (i);
3984 NamedSelectionRemoved (); /* EMIT SIGNAL */
3989 Session::reset_native_file_format ()
3991 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3993 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3994 (*i)->reset_write_sources (false);
3999 Session::route_name_unique (string n) const
4001 shared_ptr<RouteList> r = routes.reader ();
4003 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4004 if ((*i)->name() == n) {
4013 Session::route_name_internal (string n) const
4015 if (auditioner && auditioner->name() == n) {
4019 if (_click_io && _click_io->name() == n) {
4027 Session::n_playlists () const
4029 Glib::Mutex::Lock lm (playlist_lock);
4030 return playlists.size();
4034 Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force)
4036 if (!force && howmany <= _npan_buffers) {
4040 if (_pan_automation_buffer) {
4042 for (uint32_t i = 0; i < _npan_buffers; ++i) {
4043 delete [] _pan_automation_buffer[i];
4046 delete [] _pan_automation_buffer;
4049 _pan_automation_buffer = new pan_t*[howmany];
4051 for (uint32_t i = 0; i < howmany; ++i) {
4052 _pan_automation_buffer[i] = new pan_t[nframes];
4055 _npan_buffers = howmany;
4059 Session::freeze (InterThreadInfo& itt)
4061 shared_ptr<RouteList> r = routes.reader ();
4063 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4065 boost::shared_ptr<Track> t;
4067 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
4068 /* XXX this is wrong because itt.progress will keep returning to zero at the start
4078 boost::shared_ptr<Region>
4079 Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
4080 bool overwrite, vector<boost::shared_ptr<Source> >& srcs,
4081 InterThreadInfo& itt, bool enable_processing)
4083 boost::shared_ptr<Region> result;
4084 boost::shared_ptr<Playlist> playlist;
4085 boost::shared_ptr<AudioFileSource> fsource;
4087 char buf[PATH_MAX+1];
4088 ChanCount nchans(track.audio_diskstream()->n_channels());
4090 nframes_t this_chunk;
4093 SessionDirectory sdir(get_best_session_directory_for_new_source ());
4094 const string sound_dir = sdir.sound_path().to_string();
4095 nframes_t len = end - start;
4098 error << string_compose (_("Cannot write a range where end <= start (e.g. %1 <= %2)"),
4099 end, start) << endmsg;
4103 // any bigger than this seems to cause stack overflows in called functions
4104 const nframes_t chunk_size = (128 * 1024)/4;
4106 // block all process callback handling
4108 block_processing ();
4110 /* call tree *MUST* hold route_lock */
4112 if ((playlist = track.diskstream()->playlist()) == 0) {
4116 /* external redirects will be a problem */
4118 if (track.has_external_redirects()) {
4122 for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
4124 for (x = 0; x < 99999; ++x) {
4125 snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
4126 if (access (buf, F_OK) != 0) {
4132 error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg;
4137 fsource = boost::dynamic_pointer_cast<AudioFileSource> (
4138 SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
4141 catch (failed_constructor& err) {
4142 error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg;
4146 srcs.push_back (fsource);
4149 /* XXX need to flush all redirects */
4154 /* create a set of reasonably-sized buffers */
4155 buffers.ensure_buffers(DataType::AUDIO, nchans.n_audio(), chunk_size);
4156 buffers.set_count(nchans);
4158 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4159 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4161 afs->prepare_for_peakfile_writes ();
4164 while (to_do && !itt.cancel) {
4166 this_chunk = min (to_do, chunk_size);
4168 if (track.export_stuff (buffers, start, this_chunk, enable_processing)) {
4173 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
4174 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4177 if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) {
4183 start += this_chunk;
4184 to_do -= this_chunk;
4186 itt.progress = (float) (1.0 - ((double) to_do / len));
4195 xnow = localtime (&now);
4197 for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
4198 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4201 afs->update_header (position, *xnow, now);
4202 afs->flush_header ();
4206 /* construct a region to represent the bounced material */
4208 result = RegionFactory::create (srcs, 0,
4209 srcs.front()->length(srcs.front()->timeline_position()),
4210 region_name_from_path (srcs.front()->name(), true));
4215 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4216 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4219 afs->mark_for_remove ();
4222 (*src)->drop_references ();
4226 for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
4227 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
4230 afs->done_with_peakfile_writes ();
4234 unblock_processing ();
4240 Session::get_silent_buffers (ChanCount count)
4242 assert(_silent_buffers->available() >= count);
4243 _silent_buffers->set_count(count);
4245 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
4246 for (size_t i= 0; i < count.get(*t); ++i) {
4247 _silent_buffers->get(*t, i).clear();
4251 return *_silent_buffers;
4255 Session::get_scratch_buffers (ChanCount count)
4257 if (count != ChanCount::ZERO) {
4258 assert(_scratch_buffers->available() >= count);
4259 _scratch_buffers->set_count(count);
4261 _scratch_buffers->set_count (_scratch_buffers->available());
4264 return *_scratch_buffers;
4268 Session::get_mix_buffers (ChanCount count)
4270 assert(_mix_buffers->available() >= count);
4271 _mix_buffers->set_count(count);
4272 return *_mix_buffers;
4276 Session::ntracks () const
4279 shared_ptr<RouteList> r = routes.reader ();
4281 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4282 if (boost::dynamic_pointer_cast<Track> (*i)) {
4291 Session::nbusses () const
4294 shared_ptr<RouteList> r = routes.reader ();
4296 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
4297 if (boost::dynamic_pointer_cast<Track>(*i) == 0) {
4306 Session::add_automation_list(AutomationList *al)
4308 automation_lists[al->id()] = al;
4312 Session::compute_initial_length ()
4314 return _engine.frame_rate() * 60 * 5;
4318 Session::sync_order_keys (const char* base)
4320 if (!Config->get_sync_all_route_ordering()) {
4321 /* leave order keys as they are */
4325 boost::shared_ptr<RouteList> r = routes.reader ();
4327 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
4328 (*i)->sync_order_keys (base);
4331 Route::SyncOrderKeys (base); // EMIT SIGNAL
4335 /** @return true if there is at least one record-enabled diskstream, otherwise false */
4337 Session::have_rec_enabled_diskstream () const
4339 return g_atomic_int_get (&_have_rec_enabled_diskstream) == 1;
4342 /** Update the state of our rec-enabled diskstreams flag */
4344 Session::update_have_rec_enabled_diskstream ()
4346 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader ();
4347 DiskstreamList::iterator i = dsl->begin ();
4348 while (i != dsl->end () && (*i)->record_enabled () == false) {
4352 int const old = g_atomic_int_get (&_have_rec_enabled_diskstream);
4354 g_atomic_int_set (&_have_rec_enabled_diskstream, i != dsl->end () ? 1 : 0);
4356 if (g_atomic_int_get (&_have_rec_enabled_diskstream) != old) {
4357 RecordStateChanged (); /* EMIT SIGNAL */